2013-04-16 3 views
0

JList의 JLayeredPane에 버튼이 있으므로 마우스의 각 행에 아이콘 버튼을 오버레이 할 수 있습니다. 그러나 단추는 마우스 클릭을 허용하지 않습니다. 코드는 다음과 같습니다. 아무 것도 클릭하지 않으면 아무 것도 출력되지 않습니다. JList에 마우스 리스너를 추가하면 해당 리스너가 호출됩니다.JList의 JLayeredPane에있는 버튼을 클릭하는 방법

import java.awt.Color; 
import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.FontMetrics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 

import javax.swing.DefaultListCellRenderer; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JLayeredPane; 
import javax.swing.JList; 
import javax.swing.SwingConstants; 
import javax.swing.border.LineBorder; 


public class TestListLayered 
{ 
    public static class LayeredListCellRenderer extends DefaultListCellRenderer 
    { 
     @Override 
     public Component getListCellRendererComponent(final JList list, final Object value, final int index, 
       final boolean isSelected, final boolean cellHasFocus) 
     { 
      final JLayeredPane pane = new JLayeredPane(); 
      final JLabel label = (JLabel) super.getListCellRendererComponent(list, value.toString(), index, isSelected, 
        cellHasFocus); 
      label.setHorizontalAlignment(SwingConstants.RIGHT); 
      label.setBounds(0, 0, 100, 20); 
      pane.add(label, JLayeredPane.DEFAULT_LAYER); 

      final JButton edit = new JButton("e"); 
      final FontMetrics fontMetrics = edit.getFontMetrics(edit.getFont()); 
      final int height2 = (int) (1.5 * fontMetrics.getHeight()); 
      edit.setBounds(0, 0, (int) (1.5 * fontMetrics.stringWidth("e")), height2); 
      edit.addActionListener(new ActionListener() 
      { 
       @Override 
       public void actionPerformed(final ActionEvent e) 
       { 
        System.out.println("button"); 
       } 
      }); 
      pane.addMouseListener(new MouseAdapter() 
      { 
       @Override 
       public void mouseClicked(final MouseEvent e) 
       { 
        System.out.println("layeredpane"); 
       } 
      }); 
      pane.add(edit, JLayeredPane.PALETTE_LAYER); 

      pane.setPreferredSize(new Dimension(-1, height2)); 
      pane.setBorder(new LineBorder(Color.blue)); 
      return pane; 
     } 
    } 

    public static void main(final String[] args) 
    { 
     final JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 

     final JList<String> l = new JList<String>(new String[] { "item 1", "item 2" }); 
     l.setCellRenderer(new LayeredListCellRenderer()); 
     f.add(l); 

     f.pack(); 
     f.setVisible(true); 
    } 
} 
+0

그것은 수행 할 수 있습니다 ... 2 열 JTable를 사용하는 것이 좋을 것이다, camickr에 동의하지만, 몇 가지 작업을 필요로한다. 기본적으로 JList에 마우스 수신기를 추가해야합니다. 클릭하면 클릭 한 행을 결정하고 해당 행에 대한 셀 렌더러를 가져온 다음 렌더러가 버튼 경계 내에 착륙 한 클릭을 결정할 수있게해야합니다. 번역 된 마우스 포인트를 가져 와서 버튼에 전달할 수있는 방법이 필요하거나 마우스가 버튼에 있는지 여부를 알 수있는 메서드가 필요합니다. – MadProgrammer

답변

2

먼저, 난 그냥하고 싶은 말, 이것은 당신이 JListMouseListener를 추가해야합니다 ... 기본적으로

매우 이상한 것입니다. 클릭하면 선택한 행의 셀 경계를 찾고 셀 렌더러의 마우스 컨텍스트로 마우스 포인트를 변환 한 다음 마우스가 버튼 범위 내에서 클릭했는지 테스트해야합니다.

그 후에 당신이하는 일은 당신에게 달려 있습니다. 난 그냥 말하고 싶은

import java.awt.Color; 
import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.FontMetrics; 
import java.awt.Point; 
import java.awt.Rectangle; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import javax.swing.DefaultListCellRenderer; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JLayeredPane; 
import javax.swing.JList; 
import javax.swing.JScrollPane; 
import javax.swing.SwingConstants; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.border.LineBorder; 

public class TestListLayered { 

    public static class LayeredListCellRenderer extends DefaultListCellRenderer { 

     private JButton edit = new JButton("e"); 

     @Override 
     public Component getListCellRendererComponent(final JList list, final Object value, final int index, 
       final boolean isSelected, final boolean cellHasFocus) { 
      final JLayeredPane pane = new JLayeredPane(); 
      final JLabel label = (JLabel) super.getListCellRendererComponent(list, value.toString(), index, isSelected, 
        cellHasFocus); 
      label.setHorizontalAlignment(SwingConstants.RIGHT); 
      label.setBounds(0, 0, 100, 20); 
      pane.add(label, JLayeredPane.DEFAULT_LAYER); 

      final FontMetrics fontMetrics = edit.getFontMetrics(edit.getFont()); 
      final int height2 = (int) (1.5 * fontMetrics.getHeight()); 
      edit.setBounds(0, 0, (int) (1.5 * fontMetrics.stringWidth("e")), height2); 
      pane.add(edit, JLayeredPane.PALETTE_LAYER); 

      pane.setPreferredSize(new Dimension(-1, height2)); 
      pane.setBorder(new LineBorder(Color.blue)); 
      return pane; 
     } 

     protected void buttonClicked(Point p) { 
      System.out.println(edit.contains(p)); 
     } 
    } 

    public static void main(final String[] args) { 
     new TestListLayered(); 
    } 

    public TestListLayered() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       final JFrame f = new JFrame(); 
       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

       final JList<String> l = new JList<String>(new String[]{"item 1", "item 2"}); 
       l.setCellRenderer(new LayeredListCellRenderer()); 
       f.add(new JScrollPane(l)); 

       l.addMouseListener(new MouseAdapter() { 
        @Override 
        public void mouseClicked(MouseEvent e) { 
         int index = l.locationToIndex(e.getPoint()); 
         if (index > -1) { 

          Rectangle bounds = l.getCellBounds(index, index); 
          LayeredListCellRenderer cellRenderer = (LayeredListCellRenderer) l.getCellRenderer(); 
          Component renderComp = cellRenderer.getListCellRendererComponent(l, l.getModel().getElementAt(index), index, false, false); 
          renderComp.setBounds(bounds); 

          Point local = new Point(e.getPoint()); 
          local.x -= bounds.x; 
          local.y -= bounds.y; 

          cellRenderer.buttonClicked(local); 

         } 
        } 
       }); 

       f.pack(); 
       f.setVisible(true); 
      } 
     }); 
    } 
} 

, 나는

+0

JLayeredPane을 사용하고 있습니다. 특정 항목을 다른 항목 위에 올리려고합니다. 따라서 2 열 테이블을 사용하는 것은 목표를 달성하지 못합니다. 아마 하나의 컬럼 테이블을 사용할 수는 있지만 ... 조금 이상합니다. 잘 쓰여진 답변 주셔서 감사합니다! – mentics

+0

충분 : P ... – MadProgrammer

2

렌더러는 실제 구성 요소가 아닙니다. 그것은 단지 구성 요소의 그림 일뿐입니다. 따라서 버튼은 클릭에 응답하지 않습니다.

잘 모르겠지만 무엇을하려고하는지 알 수는 있지만 두 열의 JTable을 사용할 수는 있습니다. 테이블은 편집기를 지원하기 때문에 마우스 클릭에 응답합니다. Table Button Column 여기에서 당신을 도울 수있다.

관련 문제