2012-04-24 3 views
2

저는 카테고리를 사용하여 JList 구현을 찾으려고 애를 썼습니다. 내 자신을 구현할 수있을 것 같아요,하지만 셀 렌더러, 모델 및 모든 약간의 고통입니다. 그러므로 나는 너에게로 향한다!카테고리가있는 JList

내 질문에 : 범주에 지정된 항목 목록이 있으면 JTree에 표시 할 수 있습니다. 하지만 깊이가 2를 넘지 않는다는 것을 알고 있기 때문에 JTree가 과도하다고 느낍니다. 스윙에 쉬운 방법이 있는지 당신은 알고 있는가 (또는 외부 라이브러리에서) 이런 JList를 만들기 위해 :

블루 필드 레이블 (선택하지 않음)입니다

Jlist with categories http://dl.dropbox.com/u/4607638/jlist-cats.png

, 그리고 화이트 필드는을 정상적인 목록 세포?

미리 알려 주셔서 감사합니다.

+0

내가 잘못 본 것이 아니라면 찾고있는 개념을 'OutlookBar'라고합니다. 아마도이 용어에 인터넷 검색을하면 자유롭게 사용할 수있는 코드가 생깁니다. (빠른 검색을했지만 주로 상업용 솔루션을 찾았습니다.) – Robin

답변

2

아마도 example에서와 같이 JComboBox을 사용할 수 있습니다. 그렇지 않은 경우 JList을 사용하여 아이디어를 제공 할 수 있습니다.

+0

사실 꽤 깨끗하고 간단합니다. 결국 나쁜 생각 ... 감사합니다! – andli

2

대신 JTree을 사용하십시오. 그룹을 지점으로 쉽게 지원하고 항목은 남겨 둡니다. 렌더러가 필요로하는 모양을 조정할 수 있습니다

DynamicTreeDemo

.. 자세한 내용과 같은 스크린 샷에 대한 How to Use Trees를 참조하십시오. @Robin에서 언급 한 바와 같이


:

나는 하나의 JTree뿐만 아니라 사용자 정의 렌더러 단일 JList 모두 같은 단점이 있다고 생각 : 모든 노드가 선택할 수 있습니다.

분기 노드를 열어 &을 열어 선택할 수 있으므로 선택할 수있는 아무런 문제가 없습니다. '표제'가있는 목록과 약간 다른 사용자 행동입니다. 트리를 사용하는 데에는 단점이 있습니다 (예 : 분기 그룹을 지나치게 탭해야하는 번거 로움, 더 적은 키 입력/클릭으로 그룹에 액세스 할 수 있도록 분기가 기본적으로 닫힙니다.)

+1

나는 하나의'JTree'와 커스텀 렌더러를 가진 하나의'JList'는 모두 같은 단점을 가지고 있다고 생각합니다 : 모든 노드는 선택 가능합니다. 특정 노드를 선택하지 못하게하는 API는 알지 못합니다. 그리고 Solaris 스크린 샷 ... 이제 OS X 스크린 샷 팬이 된 이유를 알았습니다 :-) – Robin

+1

@Robin 편집을 참조하십시오. –

+0

예 JTree를 고려해 보았지만 질문에서 볼 수 있듯이 유용성 및 디자인 문제로 인해 제외 시켰습니다. 그것은 나의 최후의 수단이다. :) – andli

2

직접 구현할 수 있습니다 ListCellRenderer을 렌더링하고있는 항목이 부모 노드인지 또는 자식 노드인지 확인하십시오.

목록에서 상위 카테고리를 선택하지 않도록 설정하는 것은 약간 까다 롭습니다. 상위 카테고리가 선택되면 렌더러가 표시되지 않도록 수정하거나 jlist의 기본 동작을 무시할 수 있습니다.

개인적으로? JTree의 경우 목록과 똑같이 보이도록 만들 수 있지만 3 단계의 깊이와 같은 많은 다른 기능이 추가되어보다 유연 해집니다.

jtree를 사용하지 않는 이유는 두 가지입니다.

유용성 : 당신은 단지 당신이 목록을 할 수처럼 당신이 원하는 방식으로 행동하는 JTree를 수정할 수 있습니다

디자인 : 나는 그에게 한 나무를 (카테고리 및 하위 카테고리가 나무입니다) 저장할 수있는 더 나은 디자인을 생각하지 말아 편평한 명부.JPanel의의

+0

좋은 점, 감사합니다! :) – andli

5

enter image description hereenter image description here

import java.awt.*; 
import java.awt.event.*; 
import java.awt.font.*; 
import java.awt.image.BufferedImage; 
import javax.swing.*; 

public class ExpandingPanels extends MouseAdapter { 

    private ActionPanel[] aps; 
    private JPanel[] panels; 

    public ExpandingPanels() { 
     assembleActionPanels(); 
     assemblePanels(); 
    } 

    @Override 
    public void mousePressed(MouseEvent e) { 
     ActionPanel ap = (ActionPanel) e.getSource(); 
     if (ap.target.contains(e.getPoint())) { 
      ap.toggleSelection(); 
      togglePanelVisibility(ap); 
     } 
    } 

    private void togglePanelVisibility(ActionPanel ap) { 
     int index = getPanelIndex(ap); 
     if (panels[index].isShowing()) { 
      panels[index].setVisible(false); 
     } else { 
      panels[index].setVisible(true); 
     } 
     ap.getParent().validate(); 
    } 

    private int getPanelIndex(ActionPanel ap) { 
     for (int j = 0; j < aps.length; j++) { 
      if (ap == aps[j]) { 
       return j; 
      } 
     } 
     return -1; 
    } 

    private void assembleActionPanels() { 
     String[] ids = {"level 1", "level 2", "level 3", "level 4"}; 
     aps = new ActionPanel[ids.length]; 
     for (int j = 0; j < aps.length; j++) { 
      aps[j] = new ActionPanel(ids[j], this); 
     } 
    } 

    private void assemblePanels() { 
     GridBagConstraints gbc = new GridBagConstraints(); 
     gbc.insets = new Insets(2, 1, 2, 1); 
     gbc.weightx = 1.0; 
     gbc.weighty = 1.0; 
     JPanel p1 = new JPanel(new GridBagLayout()); 
     gbc.gridwidth = GridBagConstraints.RELATIVE; 
     p1.add(new JButton("button 1"), gbc); 
     gbc.gridwidth = GridBagConstraints.REMAINDER; 
     p1.add(new JButton("button 2"), gbc); 
     gbc.gridwidth = GridBagConstraints.RELATIVE; 
     p1.add(new JButton("button 3"), gbc); 
     gbc.gridwidth = GridBagConstraints.REMAINDER; 
     p1.add(new JButton("button 4"), gbc); 
     JPanel p2 = new JPanel(new GridBagLayout()); 
     gbc.gridwidth = 1; 
     gbc.anchor = GridBagConstraints.EAST; 
     p2.add(new JLabel("enter"), gbc); 
     gbc.anchor = GridBagConstraints.WEST; 
     p2.add(new JTextField(8), gbc); 
     gbc.anchor = GridBagConstraints.CENTER; 
     p2.add(new JButton("button 1"), gbc); 
     gbc.gridwidth = GridBagConstraints.REMAINDER; 
     p2.add(new JButton("button 2"), gbc); 
     JPanel p3 = new JPanel(new BorderLayout()); 
     JTextArea textArea = new JTextArea(8, 12); 
     textArea.setLineWrap(true); 
     p3.add(new JScrollPane(textArea)); 
     JPanel p4 = new JPanel(new GridBagLayout()); 
     addComponents(new JLabel("label 1"), new JTextField(12), p4, gbc); 
     addComponents(new JLabel("label 2"), new JTextField(16), p4, gbc); 
     gbc.gridwidth = 2; 
     gbc.gridy = 2; 
     p4.add(new JSlider(), gbc); 
     gbc.gridy++; 
     JPanel p5 = new JPanel(new GridBagLayout()); 
     p5.add(new JButton("button 1"), gbc); 
     p5.add(new JButton("button 2"), gbc); 
     p5.add(new JButton("button 3"), gbc); 
     p5.add(new JButton("button 4"), gbc); 
     gbc.weighty = 1.0; 
     gbc.fill = GridBagConstraints.BOTH; 
     p4.add(p5, gbc); 
     panels = new JPanel[]{p1, p2, p3, p4}; 
    } 

    private void addComponents(Component c1, Component c2, Container c, GridBagConstraints gbc) { 
     gbc.anchor = GridBagConstraints.EAST; 
     gbc.gridwidth = GridBagConstraints.RELATIVE; 
     c.add(c1, gbc); 
     gbc.anchor = GridBagConstraints.WEST; 
     gbc.gridwidth = GridBagConstraints.REMAINDER; 
     c.add(c2, gbc); 
     gbc.anchor = GridBagConstraints.CENTER; 
    } 

    private JPanel getComponent() { 
     JPanel panel = new JPanel(new GridBagLayout()); 
     GridBagConstraints gbc = new GridBagConstraints(); 
     gbc.insets = new Insets(1, 3, 0, 3); 
     gbc.weightx = 1.0; 
     gbc.fill = GridBagConstraints.HORIZONTAL; 
     gbc.gridwidth = GridBagConstraints.REMAINDER; 
     for (int j = 0; j < aps.length; j++) { 
      panel.add(aps[j], gbc); 
      panel.add(panels[j], gbc); 
      panels[j].setVisible(false); 
     } 
     JLabel padding = new JLabel(); 
     gbc.weighty = 1.0; 
     panel.add(padding, gbc); 
     return panel; 
    } 

    public static void main(String[] args) { 
     ExpandingPanels test = new ExpandingPanels(); 
     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.getContentPane().add(new JScrollPane(test.getComponent())); 
     f.setSize(360, 500); 
     f.setLocation(200, 100); 
     f.setVisible(true); 
    } 
} 

class ActionPanel extends JPanel { 

    private static final long serialVersionUID = 1L; 
    private String text; 
    private Font font; 
    private boolean selected; 
    private BufferedImage open, closed; 
    public Rectangle target; 
    private final int OFFSET = 30, PAD = 5; 

    public ActionPanel(String text, MouseListener ml) { 
     this.text = text; 
     addMouseListener(ml); 
     font = new Font("sans-serif", Font.PLAIN, 12); 
     selected = false; 
     setBackground(new Color(200, 200, 220)); 
     setPreferredSize(new Dimension(200, 20)); 
     setBorder(BorderFactory.createRaisedBevelBorder()); 
     setPreferredSize(new Dimension(200, 20)); 
     createImages(); 
     setRequestFocusEnabled(true); 
    } 

    public void toggleSelection() { 
     selected = !selected; 
     repaint(); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     int w = getWidth(); 
     int h = getHeight(); 
     if (selected) { 
      g2.drawImage(open, PAD, 0, this); 
     } else { 
      g2.drawImage(closed, PAD, 0, this); 
     } 
     g2.setFont(font); 
     FontRenderContext frc = g2.getFontRenderContext(); 
     LineMetrics lm = font.getLineMetrics(text, frc); 
     float height = lm.getAscent() + lm.getDescent(); 
     float x = OFFSET; 
     float y = (h + height)/2 - lm.getDescent(); 
     g2.drawString(text, x, y); 
    } 

    private void createImages() { 
     int w = 20; 
     int h = getPreferredSize().height; 
     target = new Rectangle(2, 0, 20, 18); 
     open = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
     Graphics2D g2 = open.createGraphics(); 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     g2.setPaint(getBackground()); 
     g2.fillRect(0, 0, w, h); 
     int[] x = {2, w/2, 18}; 
     int[] y = {4, 15, 4}; 
     Polygon p = new Polygon(x, y, 3); 
     g2.setPaint(Color.green.brighter()); 
     g2.fill(p); 
     g2.setPaint(Color.blue.brighter()); 
     g2.draw(p); 
     g2.dispose(); 
     closed = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
     g2 = closed.createGraphics(); 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     g2.setPaint(getBackground()); 
     g2.fillRect(0, 0, w, h); 
     x = new int[]{3, 13, 3}; 
     y = new int[]{4, h/2, 16}; 
     p = new Polygon(x, y, 3); 
     g2.setPaint(Color.red); 
     g2.fill(p); 
     g2.setPaint(Color.blue.brighter()); 
     g2.draw(p); 
     g2.dispose(); 
    } 
} 
+1

많은 세부 사항을 가진 중대한 응답, 감사합니다. – andli