2013-04-07 3 views
7

내 JTable의 셀을 선택한 패널과 수평으로 정렬하고 싶습니다.
여기에 내 문제를 설명하는 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())); 
        } 
       } 
      } 
     } 
    } 
} 
+0

btw, +1 SSCCE를 제공합니다. BTW : 실제 코드에서는 setSelected에서 청취자가 아닌 repaint를 수행합니다. 그러나 이것은 단지 예일뿐입니다 :-) – kleopatra

+0

팁, 감사합니다. 어쨌든 JList를 사용하기 위해 편집 할 것이라고 생각합니다. mKorbel이 명확하게 말하도록 제안했지만 게시물이 삭제되었습니다. 귀하의 답변에 감사드립니다. – jerome

+0

지난 주에 가장 좋은 질문에 대해 (덧글을 삭제 한) 댓글을 달았습니다. 그런 다음 댓글을 달았습니다. [답변은 훌륭한 품질로 제공되지만 여기에서 검색하는 방법을 알아야합니다.] (http : // stackoverflow. com/questions/15868553/fit-all-components-from-jframe에서 실제 크기의 윈도우/15868588 # comment22600617_15868588), JComponets를 JList 또는 JTable에 넣지 말고 설명 만, String 값은 JButton, XxxRenderer에 대한이 작업 (페인팅 JButton)을 허용합니다. 귀하의 upvote – mKorbel

답변

3

그것은 기본적인 수학 그리고 그것은 뷰포트에 액세스 할 필요가 없습니다 :이 조각 패널의 부모 테이블 모두의 뷰의 뷰포트가 같은 크기를 가지고 있다고 가정

// 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); 

주, 그래서 중 하나를 제거 헤더를 패널의 scrollPane에 추가하는지, 2 개의 scrollPane의 뷰포트를 정렬 할 수있는 LayoutManager를 사용합니다.

3

뷰포트. setViewPosition (pt); as shown here.

+0

에 대한 그녀의 응답이 그 예제가 옳다는 것 (그 자체로 놀라운, java2s.com ;-)에서 오는 질문에 대한 문구에서 액세스 할 필요가 없습니다. 뷰포트 :-) – kleopatra

관련 문제