Java 以编程方式滚动
我希望JTable的单元格与所选面板水平对齐。Java 以编程方式滚动,java,swing,jtable,Java,Swing,Jtable,我希望JTable的单元格与所选面板水平对齐。以下是一个SSCCE来说明我的问题。谢谢你的帮助。 public class TableCellAlignment { private final static int MAX = 50; private static SelectablePanel[] selectablePanels = new SelectablePanel[MAX]; private static JScrollPane slaveScrollPan
以下是一个SSCCE来说明我的问题。谢谢你的帮助。
public class TableCellAlignment {
private final static int MAX = 50;
private static SelectablePanel[] selectablePanels = new SelectablePanel[MAX];
private static JScrollPane slaveScrollPane = new JScrollPane();
private static JScrollPane masterScrollPane = new JScrollPane();
private static JTable slaveTable = new JTable();
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new TableCellAlignment().createGUI();
}
});
}
private static void createGUI() {
JFrame f = new JFrame("TableCellAlignment");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel masterPanel = new JPanel(new GridLayout(MAX, 1));
Integer[][] objs = new Integer[MAX][1];
for (int i = 0; i < MAX; i++) {
objs[i][0] = new Integer(i);
SelectablePanel masterSelectablePanel = new SelectablePanel();
masterSelectablePanel.setNum(i);
selectablePanels[i] = masterSelectablePanel;
masterPanel.add(masterSelectablePanel);
}
DefaultTableModel model = new DefaultTableModel(objs, new Object[]{"Column1"});
model.addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
slaveTable.setRowHeight(20);
}
});
}
});
model.addRow(objs);
slaveTable.setModel(model);
final JPanel p = new JPanel(new GridLayout(1, 2));
masterScrollPane.setViewportView(masterPanel);
slaveScrollPane.setViewportView(slaveTable);
p.add(masterScrollPane);
p.add(slaveScrollPane);
f.add(p);
f.setSize(400, 200);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static class SelectablePanel extends JPanel {
private PropertyChangeSupport cs;
private int num;
private boolean selected = false;
public SelectablePanel() {
cs = new PropertyChangeSupport(this);
cs.addPropertyChangeListener(new SelectedPropertyChangeListener());
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
setSelected(true);
}
});
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public boolean isSelected() {
return selected;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (selected) {
Color c = g.getColor();
g.setColor(Color.blue);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.white);
FontMetrics fm = g.getFontMetrics();
g.drawString("" + getNum(), getWidth() / 2, (getHeight() + (fm.getAscent() - fm.getDescent())) / 2);
g.setColor(c);
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(100, 20);
}
public void setSelected(boolean selected) {
boolean oldVal = isSelected();
this.selected = selected;
cs.firePropertyChange("selected", oldVal, selected);
repaint();
}
private class SelectedPropertyChangeListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("selected")) {
boolean selected = (boolean) evt.getNewValue();
if (selected) {
for (int i = 0; i < MAX; i++) {
SelectablePanel masterSelectablePanel = selectablePanels[i];
if (i != getNum() && masterSelectablePanel.isSelected()) {
masterSelectablePanel.setSelected(false);
}
}
slaveTable.setRowSelectionInterval(getNum(), getNum());
final JViewport viewport = slaveScrollPane.getViewport();
Rectangle rect = new Rectangle(getBounds().x, getBounds().y, 1, 1);
Rectangle r2 = viewport.getVisibleRect();
slaveTable.scrollRectToVisible(new Rectangle(rect.x, rect.y, (int)r2.getWidth(), (int)r2.getHeight()));
}
}
}
}
}
}
公共类TableCellAlignment{
私有最终静态int MAX=50;
私有静态SelectablePanel[]selectablePanels=新建SelectablePanel[MAX];
私有静态JScrollPane slaveScrollPane=new JScrollPane();
私有静态JScrollPane masterScrollPane=新JScrollPane();
私有静态JTable slaveTable=新JTable();
/**
*@param指定命令行参数
*/
公共静态void main(字符串[]args){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
新建TableCellAlignment().createGUI();
}
});
}
私有静态void createGUI(){
JFrame f=新JFrame(“TableCellAlignment”);
f、 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel主面板=新JPanel(新网格布局(最大值,1));
整数[][]objs=新整数[MAX][1];
对于(int i=0;i视口(pt) 这是基本数学,不需要访问视口:
// in the isSelected block of the propertyChangeListener:
JComponent current = (JComponent) evt.getSource();
slaveTable.setRowSelectionInterval(getNum(), getNum());
// get the cellRect of the selected cell
Rectangle cellRect = slaveTable.getCellRect(getNum(), 0, false);
// get the bounds of the selected panel
Rectangle panelRect = current.getBounds();
// get the visible rect of the selected panel's parent
Rectangle parentVisibleRect = ((JComponent) current.getParent()).getVisibleRect();
// the diff above the current (to the parent's visible rect)
int aboveCurrent = panelRect.y - parentVisibleRect.y;
// translate the cell rect
cellRect.y = Math.max(cellRect.y - aboveCurrent, 0);
// adjust size to slaveTable's visible height
cellRect.height = slaveTable.getVisibleRect().height;
slaveTable.scrollRectToVisible(cellRect);
请注意,此代码段假定面板父级和表的视图视口具有相同的大小,因此请从表中删除标题,或向面板的滚动窗格添加标题,或使用可以对齐两个滚动窗格的视口的LayoutManager。该示例是正确的(来自java2s.com,本身令人惊讶;-)但是在这个问题的上下文中,没有必要访问视口:-)顺便说一句,提供SSCCE需要+1。顺便说一句:在现实世界的代码中,您将在集合中重新绘制,而不是在侦听器中。但是,这只是一个例子:-)好的,谢谢你的提示。我想我无论如何都会编辑它以使用JList,我想这就是mKorbel