JScrollPane 안에 JTable이 있고, 고정 된 수의 테이블 행에 JScrollPane을 맞추기 위해 getPreferredScrollableViewportSize를 재정 의하여 스크롤 막대가 필요할 때 표시되도록합니다. 또한 SO에서 찾은 코드 부분을 사용하여 내용에 맞게 테이블 열의 크기를 조정했습니다.getPreferredScrollableViewportSize를 적절히 오버라이드
내가 가지고있는 문제는, 내가 dinamically 테이블에 더 넓은 행을 추가 할 때, 수평 JScrollBar가 표시되지 않는다는 것입니다. JTable, JViewport 및 JScrollPane이 revalidate(), repaint(), doLayout() 등을 올바르게 호출하도록 강제하는 여러 가지 방법을 시도했지만 성공하지 못했습니다.
물론 JFrame에서 pack() 메서드를 호출 할 수 있지만 전체 스크롤 패널의 너비가 커지고 가로 스크롤 막대가 나타나지 않습니다.
내가 무엇이 누락 되었습니까?
여기에는 MVCE가 있지만 그냥 못생긴 장난감 예제 일 뿐이지 만 원치 않는 동작을 복제하기에 충분해야합니다.
도움 주셔서 감사합니다.
코드 :
import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.table.*;
public class Main
{
public static void main (String [] a) {
SwingUtilities.invokeLater (new Runnable() {
public void run() {
initGUI();
}
});
}
private static void initGUI() {
final DataTable table = new DataTable();
JPanel container = new JPanel (new BorderLayout (0, 20));
container.add (new JScrollPane (table));
container.add (new JButton (new AbstractAction ("Add wider row") {
public void actionPerformed (ActionEvent e) {
table.addRow();
// some of many useless attempts ...
// table.resizeColumnWidth();
// table.revalidate();
}
}), BorderLayout.SOUTH);
container.setBorder (new EmptyBorder (10, 10, 10, 10));
JFrame frame = new JFrame ("Test");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.setResizable (false);
frame.setContentPane (container);
frame.setLocationRelativeTo (null);
frame.pack();
frame.setVisible (true);
}
}
class DataTable extends JTable
{
private static final int VISIBLE_ROWS = 5;
DataTable() {
String [][] data = new String [][] {
{"SomeText", "SomeText"},
{"SomeText", "SomeText"},
{"SomeText", "SomeText"},
{"SomeText", "SomeText"},
{"SomeText", "SomeText"},
{"SomeText", "SomeText"}
};
setModel (new DefaultTableModel (data, new String [] {"", ""}) {
@Override public boolean isCellEditable (int row, int column) {
return false;
}
});
columnModel.setColumnMargin (20);
setBorder (null);
setFocusable (false);
setRowSelectionAllowed (false);
setShowGrid (false);
setTableHeader (null);
resizeColumnWidth();
}
public void addRow() {
((DefaultTableModel) getModel()).addRow (new String [] {"SomeLongerText", "SomeLongerText"});
}
private int calculateColumnWidth (int column) {
TableColumn tableColumn = columnModel.getColumn (column);
int width = 0;
for (int row=0; row<getRowCount(); row++) width = Math.max (prepareRenderer (getCellRenderer (row, column), row, column).getPreferredSize().width, width);
return width + getIntercellSpacing().width;
}
@Override public Dimension getPreferredScrollableViewportSize() {
int columnsWidth = 0;
for (int column=0; column<getColumnCount(); column++) columnsWidth += calculateColumnWidth (column);
return new Dimension (columnsWidth, VISIBLE_ROWS * getRowHeight());
}
protected void resizeColumnWidth() {
for (int column=0; column<getColumnCount(); column++) columnModel.getColumn (column).setPreferredWidth (calculateColumnWidth (column));
}
}
편집 :
덕분에 내가 원하는 자동 조절 모드를 설정하고 resizeColumnWidth 방법을 행이 추가 될 때마다 리콜 문제를 해결, @camickr합니다. 이미 개별적으로 시도했다, 난 지금은 잘 작동 전, 업데이트 된 코드 아래에 게시, 내가 모두 :)
Hovewer을 사용하지 않은 믿을 수 없어 :
import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.table.*;
public class Main
{
public static void main (String [] a) {
SwingUtilities.invokeLater (new Runnable() {
public void run() {
initGUI();
}
});
}
private static void initGUI() {
final DataTable table = new DataTable();
JPanel container = new JPanel (new BorderLayout (0, 20));
container.add (new JScrollPane (table));
container.add (new JButton (new AbstractAction ("Add wider row") {
public void actionPerformed (ActionEvent e) {
table.addRow();
}
}), BorderLayout.SOUTH);
container.setBorder (new EmptyBorder (10, 10, 10, 10));
JFrame frame = new JFrame ("Test");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.setResizable (false);
frame.setContentPane (container);
frame.setLocationRelativeTo (null);
frame.pack();
frame.setVisible (true);
}
}
class DataTable extends JTable
{
private static final int VISIBLE_ROWS = 5;
DataTable() {
String [][] data = new String [][] {
{"SomeText", "SomeText"},
{"SomeText", "SomeText"},
{"SomeText", "SomeText"},
{"SomeText", "SomeText"},
{"SomeText", "SomeText"},
{"SomeText", "SomeText"}
};
setModel (new DefaultTableModel (data, new String [] {"", ""}) {
@Override public boolean isCellEditable (int row, int column) {
return false;
}
});
columnModel.setColumnMargin (20);
setAutoResizeMode (AUTO_RESIZE_OFF);
setBorder (null);
setFocusable (false);
setRowSelectionAllowed (false);
setShowGrid (false);
setTableHeader (null);
resizeColumnWidth();
}
public void addRow() {
((DefaultTableModel) getModel()).addRow (new String [] {"SomeLongerText", "SomeLongerText"});
resizeColumnWidth();
}
private int calculateColumnWidth (int column) {
TableColumn tableColumn = columnModel.getColumn (column);
int width = 0;
for (int row=0; row<getRowCount(); row++) width = Math.max (prepareRenderer (getCellRenderer (row, column), row, column).getPreferredSize().width, width);
return width + getIntercellSpacing().width;
}
@Override public Dimension getPreferredScrollableViewportSize() {
int columnsWidth = 0;
for (int column=0; column<getColumnCount(); column++) columnsWidth += calculateColumnWidth (column);
return new Dimension (columnsWidth, VISIBLE_ROWS * getRowHeight());
}
protected void resizeColumnWidth() {
for (int column=0; column<getColumnCount(); column++) columnModel.getColumn (column).setPreferredWidth (calculateColumnWidth (column));
}
}
질문에 MCVE를 게시 해 주셔서 감사합니다. (+1) 그리고 또한 당연히 camickr에. –