위 링크는 최신이 아니므로 여기에 최신 정보가 있습니다.
단순히 JTable을 사용하면 초기로드 속도가 크게 향상되지만 스크롤을 처음 시작할 때 약간 느려집니다. 그리고 행 높이가 조정해야하는 새로운 문제가 있습니다. getTableCellRendererComponent
메서드를 사용하면 행, 테이블 및 구성 요소에 액세스 할 수 있으므로 TableCellRenderer
을 구현하여 사용자 정의 렌더러 내에서 쉽게 수행 할 수 있습니다. 그러나 동일한 코드를 호출하는 테이블의 업데이트가 실행됩니다. 적절하게 코딩하면 문제가되지 않습니다. 그래도 다른 곳에 넣는 것이 더 나은 습관입니다. JViewport
에 리스너를 추가하고 현재 볼 수있는 행만 업데이트했습니다. The code I based this on is here
또는 ListCellRenderer
을 사용하여 HTML과 비슷한 JPanel
을 반환 할 수 있습니다. JTextArea
만 필요한 경우 너비를 설정하여 기본 높이가 올바르게 설정되어 있는지 확인해야합니다 (like in this answer). 다시 행의 너비를 업데이트해야하며 JViewport
을 기반으로이를 수행하는 것이 좋습니다.
두 가지 방법의 성능에 대해 궁금한 점이 있다면 JPanel
을 반환하는 사용자 정의 렌더러는 JLabel
s 렌더링 HTML보다 빠릅니다. 몇 천 개의 항목이있는 목록에서도 두 가지 모두 상당히 빠릅니다. 언급했듯이 처음 스크롤 할 때 약간 느려질 수 있습니다.
마지막으로, 여기에 짧은 비교 자신을 만들 수 있습니다 일부 코드입니다 :
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.Timer;
import java.util.concurrent.ExecutionException;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class JTableHtmlTest extends JFrame {
protected static final long serialVersionUID = 1L;
public static class Item {
public int id;
public String msg;
}
static class TableModel extends AbstractTableModel {
private static final long serialVersionUID = JListTest.serialVersionUID;
private Item[] items = new Item[] {};
public int getRowCount() {
return items.length;
}
public int getColumnCount() {
return 1;
}
public Object getValueAt(int rowIndex, int columnIndex) {
return items[rowIndex];
}
@Override
public String getColumnName(int column) {
return "";
}
public void updateItems() {
SwingWorker<Item[], Void> worker = new SwingWorker<Item[], Void>() {
@Override
protected Item[] doInBackground() throws Exception {
final Item[] tempList = new Item[3000];
for (int i = 0; i < tempList.length; i++) {
Item item = new Item();
item.id = (int) (Math.random() * 10000);
item.msg = "This is the default message that has to be"
+ " long enough to wrap around a few times so that"
+ " we know things are working. It's rather tedious to write.";
tempList[i] = item;
}
return tempList;
}
@Override
protected void done() {
try {
items = get();
fireTableDataChanged();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
};
worker.execute();
}
}
public static class TableRenderer implements TableCellRenderer {
private static final String strColor = "#EDF5F4";
private static final Color strideColor = Color.decode(strColor);
JLabel htmlLabel = new JLabel();
JPanel noHtmlPanel = new JPanel();
JLabel noHtmlLabel = new JLabel();
JTextArea noHTMLTextArea = new JTextArea();
Item toRender = null;
boolean useHtml = false;
public TableRenderer() {
noHTMLTextArea.setWrapStyleWord(false);
noHTMLTextArea.setLineWrap(true);
noHTMLTextArea.setOpaque(false);
Font defaultFont = noHtmlLabel.getFont();
Font boldFont = defaultFont.deriveFont(Font.BOLD);
noHtmlLabel.setFont(boldFont);
noHtmlLabel.setOpaque(false);
noHtmlPanel.setLayout(new BorderLayout());
noHtmlPanel.add(noHtmlLabel, BorderLayout.NORTH);
noHtmlPanel.add(noHTMLTextArea, BorderLayout.SOUTH);
}
public void setUseHtml(boolean useHtml) {
this.useHtml = useHtml;
}
public Component getJlabelRenderer(JTable table, Item value, int row) {
String colorString = "";
if (row % 2 == 0) {
colorString = "background-color:" + strColor + ";";
}
if (toRender != value) {
toRender = value;
htmlLabel.setText("<html><div style='padding:2px;" + "width:"
+ table.getWidth() + ";" + colorString
+ "color:black;'>"
+ "<div style='padding:2px;font-weight:500;'>"
+ "Item " + value.id + "</div>" + value.msg
+ "</div></html>");
}
return htmlLabel;
}
public Component getNoHtmlRenderer(JTable table, Item value, int row) {
if (toRender != value) {
toRender = value;
noHtmlLabel.setText("Item " + value.id);
noHTMLTextArea.setText(value.msg);
if (row % 2 == 0) {
noHtmlPanel.setBackground(strideColor);
noHtmlPanel.setOpaque(true);
} else {
noHtmlPanel.setOpaque(false);
}
}
return noHtmlPanel;
}
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
if (useHtml) {
return getJlabelRenderer(table, (Item) value, row);
} else {
return getNoHtmlRenderer(table, (Item) value, row);
}
}
}
public JTableHtmlTest() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel controlPanel = new JPanel();
JButton updaterControl = new JButton("Update 3000");
final JCheckBox useHtmlControl = new JCheckBox("Use HTML");
final TableModel model = new TableModel();
final JTable table = new JTable(model);
final TableRenderer renderer = new TableRenderer();
JScrollPane scrollPane = new JScrollPane(table);
final JLabel durationIndicator = new JLabel("0");
controlPanel.add(useHtmlControl, BorderLayout.WEST);
controlPanel.add(updaterControl, BorderLayout.EAST);
getContentPane().add(controlPanel, BorderLayout.PAGE_START);
getContentPane().add(scrollPane, BorderLayout.CENTER);
getContentPane().add(durationIndicator, BorderLayout.PAGE_END);
table.setDefaultRenderer(Object.class, renderer);
// Only update the JTable row heights when they are in view
final JViewport viewport = scrollPane.getViewport();
viewport.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
Rectangle viewRect = viewport.getViewRect();
int first = table.rowAtPoint(new Point(0, viewRect.y));
if (first == -1) {
return;
}
int last = table.rowAtPoint(new Point(0, viewRect.y
+ viewRect.height - 1));
if (last == -1) {
last = model.getRowCount() - 1;
}
int column = 0;
for (int row = first; row <= last; row++) {
Component comp = table.prepareRenderer(
table.getCellRenderer(row, column),
row, column);
int rowHeight = comp.getPreferredSize().height;
table.setRowHeight(row, rowHeight);
}
}
});
updaterControl.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
renderer.setUseHtml(useHtmlControl.isSelected());
model.updateItems();
}
});
Timer counter = new Timer();
counter.schedule(new TimerTask() {
@Override
public void run() {
String previousCounter = durationIndicator.getText();
final String newCounter = Integer.toString(Integer
.parseInt(previousCounter) + 1);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
durationIndicator.setText(newCounter);
setTitle(newCounter);
}
});
}
}, 0, 100);
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
JTableHtmlTest jlt = new JTableHtmlTest();
jlt.pack();
jlt.setSize(300, 300);
jlt.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
난 당신이 함께 어디로 가고 있는지 볼 수 있지만, 나는 나에게 여러 라인 항목을 표시 할 수 뭔가가 필요합니다. 다음은 일반적인 형식 항목입니다. E995.9 다른 종류의 재래식 전쟁에 의한 전쟁으로 인한 상해
@Elliott : HTML 구문 분석을 피하면서 여러 줄 텍스트를 렌더링하려면 사용자 정의 구성 요소 (또는 사용자 정의 LabelUI : http://codeguru.earthweb.com/java/articles/198.shtml)를 사용할 수 있습니다. 그것이 실제로 병목인지 여부를 확인하기 위해). 또는 JList 대신 단일 열 JTable을 사용해보십시오. IIRC JTable은 JList보다 훨씬 많은 양의 데이터 용으로 설계되었으며 실제로 표시되는 요소 만 렌더링합니다. –
JTextArea 구성 요소를 사용하여 텍스트를 표시했습니다. 그것은 트릭을했다. ListCellRenderer 제안은 나를 올바른 방향으로 가리켰다. 다음 샘플 코드를 사용하여이 문제를 해결할 수있었습니다. http://forums.sun.com/thread.jspa?threadID=552711 – Elliott