2016-08-04 3 views
1

내가 학교에서해야하는 프로젝트에 얽매여 있습니다.Java ListCellRenderer 및 JList : 핸들 선택

"단순한"UI를 위해 JList 사용자 지정을 만들려고했습니다. 사용 사례는 주문 목록을 표시해야하며 사용자는 하나를 선택하고 두 개의 단추를 눌러 읽거나 마쳤 으면 설정해야합니다 (읽기 그리고 done) "unsetters"(나는 t, f, t, f를 계속 쓰는 Order 클래스에서 2 개의 부울을 사용하고 있습니다.). 일단 Done 버튼을 누를 때까지 선택된 행은 녹색으로 변하고 그 색에 영구히 남아 있어야합니다. Order 클래스의 "is_read"플래그와 관련하여 선택된 행을 영구히 노란색으로 바꿔야하는 버튼 "Read"와 동일합니다. 내 문제는 한 번 내 테스트 파일을 실행,

public class CookListCellRender extends JLabel implements ListCellRenderer<Order>{ 

public CookListCellRender(){ 
    setOpaque(true); 
} 

@Override 
public Component getListCellRendererComponent(JList<? extends Order> list, Order value, int index, boolean isSelected, boolean cellHasFocus) { 

    setLayout(new FlowLayout()); 
    setText(value.getNameEl()); 
    list.setVisibleRowCount(30); 
    list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
    setFont(new Font("Arial",Font.ITALIC,17)); 

    if (isSelected) { 
     setBackground(Color.BLUE); 
     setForeground(Color.BLUE); 
    } else { 
     setBackground(getBackground()); 
     setForeground(getForeground()); 
    } 

    if(value.getOrderRead()){ 
     setBackground(Color.YELLOW); 
    }else{ 
     setBackground(Color.WHITE); 
    } 

    if(value.getOrderDone()){ 
     setBackground(Color.GREEN); 
    }else{ 
     setBackground(Color.WHITE); 
    } 
    return this; 
} 

} 

입니다

, 모든 것이 제대로 팝업하지만 행을 선택했을 때 그 둘 중 하나를 누릅니다

일부 관련 게시물을 읽은 후, 나는이 정의 ListCellRenderer을 썼다 버튼은 새로운 행을 선택할 때까지는 아무 일도 일어나지 않습니다. 내가 선택한 행의 색상을 녹색 또는 노란색으로 바꿉니다.

저는 이것이 내 사용자 정의 셀 렌더러와 관련된 문제이며, 여전히 사용법을 배우고 있기 때문에 꽤 혼란 스럽습니다.

여기 UI의 나머지 관련 코드가 있습니다. 아마도 유용 할 것입니다. ... 버튼과 청취자는 별도의 클래스 (사용자 정의 JPanel)에 있지만, 잘 작동 사람들은, 그래서

클래스 (직접 내 테스트 클래스에 의해 호출) InitGraphics :이

public class InitGraphics { 

Cook c; 
JList list; 

public InitGraphics(Cook cuoco){ 
    c=cuoco; 
    initUi(); 
    } 

private void initUi() { 
    JFrame frame = new JFrame("Cucina"); 
    list =new JList(c.getOrdersCopy().toArray()); 
    list.setCellRenderer(new CookListCellRender()); 
    JScrollPane panel = new JScrollPane(list); 
    panel.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); 
    panel.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); 
    ButtonPanel buttonPanel = new ButtonPanel(c.getOrdersCopy(),list); 
    buttonPanel.setLayout(new FlowLayout()); 
    frame.add(buttonPanel,BorderLayout.NORTH); 
    frame.add(panel,BorderLayout.CENTER); 
    frame.setVisible(true); 
    frame.setSize(600, 400); 
    frame.setDefaultCloseOperation(EXIT_ON_CLOSE); 
    } 
} 
+3

을 읽을 수있어, 더 나는 ** ** 작성할를 촉구하지 않으며 (HTTP를 유효한 [sscce]를 게시 : // sscce.org). 심각하고 즉각적인 도움이 필요한 경우. 그렇지 않으면 코드가 우리에게 쓸모가 없으며 문제를 이해하는 데 한계가 있습니다. –

+1

예를 들면 : 우리 중 누구도이 코드를 컴파일하거나 실행할 수 없습니다.우리는 전체 프로그램을 보거나 문제와 관련없는 많은 양의 코드를보고 싶지 않지만 컴파일되지 않고 우리를 위해 컴파일되고 실행되는 가장 작은 예제로 코드를 압축 할 수 있다면 문제가 있음을 보여줍니다. 코드 형식의 텍스트로 질문에 게시 할 수있을만큼 작기 때문에 문제를 아주 빨리 해결할 수 있습니다. –

+0

죄송합니다, 인터넷에 연결되지 않았습니다. Btw 나는 전에 sce에 대해 들어 본 적이 없지만 나는 ... 나는 140 선의 코드를 가지고있다. 나는 매우 적합하다고 생각하지 않지만 그의 직업은 훌륭하다고 생각한다. "자바 베테랑"이 아니므로 최선을 다했는데 이미 게시 된 코드를 편집하지 않으려면 [pastebin] (http://pastebin.com/QUP0v8ke)을 사용하십시오. – A7X

답변

3

을 죽이고있다 너 :

} else { 
     setBackground(getBackground()); 
     setForeground(getForeground()); 
    } 

전혀 변경되지 않습니다. 나는 당신이 원하는 생각이 코드에 전혀 일을 할 수

} else { 
     setBackground(null); 
     setForeground(null); 
    } 

참고, 내가 만들어야했습니다 내 자신의 SSCCE :

향후
import java.awt.*; 
import javax.swing.*; 

public class InitGraphics { 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> { 
      final DefaultListModel<Order> orderModel = new DefaultListModel<>(); 
      orderModel.addElement(new Order("One")); 
      orderModel.addElement(new Order("Two")); 
      orderModel.addElement(new Order("Three")); 
      orderModel.addElement(new Order("Four")); 
      orderModel.addElement(new Order("Five")); 

      JList<Order> orderList = new JList<>(orderModel); 
      orderList.setCellRenderer(new CookListCellRender()); 

      JPanel panel = new JPanel(); 
      panel.add(new JScrollPane(orderList)); 

      JOptionPane.showMessageDialog(null, panel); 
     }); 
    } 
} 

class CookListCellRender extends JLabel implements ListCellRenderer<Order> { 

    public CookListCellRender() { 
     setOpaque(true); 
    } 

    @Override 
    public Component getListCellRendererComponent(JList<? extends Order> list, Order value, int index, 
      boolean isSelected, boolean cellHasFocus) { 

     setLayout(new FlowLayout()); 
     setText(value.getNameEl()); 
     list.setVisibleRowCount(30); 
     list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
     setFont(new Font("Arial", Font.ITALIC, 17)); 

     if (isSelected) { 
      setBackground(Color.BLUE); 
      setForeground(Color.BLUE); 
     } else { 
      // TODO: fix! 
      // setBackground(getBackground()); 
      // setForeground(getForeground()); 
      setBackground(null); 
      setForeground(null); 
     } 

     if (value.getOrderRead()) { 
      setBackground(Color.YELLOW); 
     } else { 
      setBackground(Color.WHITE); 
     } 

     if (value.getOrderDone()) { 
      setBackground(Color.GREEN); 
     } else { 
      setBackground(Color.WHITE); 
     } 
     return this; 
    } 

} 

class Order { 

    private String nameE1; 
    private boolean orderDone; 
    private boolean orderRead; 

    public Order(String nameE1) { 
     this.nameE1 = nameE1; 
    } 

    public String getNameEl() { 
     return nameE1; 
    } 

    public boolean getOrderDone() { 
     return orderDone; 
    } 

    public boolean getOrderRead() { 
     return orderRead; 
    } 

    public void setOrderDone(boolean orderDone) { 
     this.orderDone = orderDone; 
    } 

    public void setOrderRead(boolean orderRead) { 
     this.orderRead = orderRead; 
    } 

} 

, 우리를 위해이 일을하시기 바랍니다 당신이 도움을 구하는 사람이기 때문에 우리는 자원 봉사자입니다.

는 또한이 :

list.setVisibleRowCount(30); 
    list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 

는 렌더러 내에서 이런 종류의 작업을 수행하지 마십시오. 이 코드는 렌더러가 아니라 JList를 생성해야한다.

여기 내 최신 SSCCE 명확 포함 하나가// 난 강력하게 제안 완료 버튼

import java.awt.Color; 
import java.awt.Component; 
import java.awt.Font; 
import java.awt.event.*; 
import java.util.List; 

import javax.swing.*; 

public class InitGraphics { 
    @SuppressWarnings("serial") 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> { 
      final DefaultListModel<Order> orderModel = new DefaultListModel<>(); 
      orderModel.addElement(new Order("One")); 
      orderModel.addElement(new Order("Two")); 
      orderModel.addElement(new Order("Three")); 
      orderModel.addElement(new Order("Four")); 
      orderModel.addElement(new Order("Five")); 

      final JList<Order> orderList = new JList<>(orderModel); 
      orderList.setCellRenderer(new CookListCellRender()); 
      orderList.setVisibleRowCount(5); 

      JPanel panel = new JPanel(); 
      // panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS)); 
      panel.add(new JScrollPane(orderList)); 

      panel.add(new JButton(new AbstractAction("Read") { 

       @Override 
       public void actionPerformed(ActionEvent e) { 
        List<Order> selectedOrders = orderList.getSelectedValuesList(); 
        for (Order order : selectedOrders) { 
         order.setOrderRead(true); 
        } 
        orderList.repaint(); 
       } 
      })); 
      panel.add(new JButton(new AbstractAction("Done") { 

       @Override 
       public void actionPerformed(ActionEvent e) { 
        List<Order> selectedOrders = orderList.getSelectedValuesList(); 
        for (Order order : selectedOrders) { 
         order.setOrderDone(true); 
        } 
        orderList.repaint(); 
       } 
      })); 
      panel.add(new JButton(new AbstractAction("Clear") { 

       @Override 
       public void actionPerformed(ActionEvent e) { 

        for (int i = 0; i < orderModel.size(); i++) { 
         orderModel.getElementAt(i).setOrderDone(false); 
         orderModel.getElementAt(i).setOrderRead(false); 
        } 
        orderList.repaint(); 
       } 
      })); 


      JFrame frame = new JFrame("Test List"); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.add(panel); 
      frame.pack(); 
      frame.setLocationRelativeTo(null); 
      frame.setVisible(true); 
     }); 
    } 
} 

@SuppressWarnings("serial") 
class CookListCellRender extends JLabel implements ListCellRenderer<Order> { 

    public CookListCellRender() { 
     setOpaque(true); 
    } 

    @Override 
    public Component getListCellRendererComponent(JList<? extends Order> list, Order value, int index, 
      boolean isSelected, boolean cellHasFocus) { 

     // setOpaque(true); // !! 

     // !! setLayout(new FlowLayout()); 
     setText(value.getNameEl()); 
     // !! list.setVisibleRowCount(30); 
     // !! list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
     setFont(new Font("Arial", Font.ITALIC, 17)); 

     if (isSelected) { 
      setBackground(Color.BLUE); 
      setForeground(Color.BLUE); 
     } else { 
      // TODO: fix! 
      // setBackground(getBackground()); 
      // setForeground(getForeground()); 
      setBackground(null); 
      setForeground(null); 
     } 

     if (value.getOrderRead()) { 
      setBackground(Color.YELLOW); 
     } else { 
      setBackground(Color.WHITE); 
     } 

     if (value.getOrderDone()) { 
      setBackground(Color.GREEN); 
     } else { 
      setBackground(Color.WHITE); 
     } 
     return this; 
    } 

} 

class Order { 

    private String nameE1; 
    private boolean orderDone; 
    private boolean orderRead; 

    public Order(String nameE1) { 
     this.nameE1 = nameE1; 
    } 

    public String getNameEl() { 
     return nameE1; 
    } 

    public boolean getOrderDone() { 
     return orderDone; 
    } 

    public boolean getOrderRead() { 
     return orderRead; 
    } 

    public void setOrderDone(boolean orderDone) { 
     this.orderDone = orderDone; 
    } 

    public void setOrderRead(boolean orderRead) { 
     this.orderRead = orderRead; 
    } 

} 
+0

와우 거기에 새로운 것들이 많이 있습니다 ... 내가 AbstractAction이 이전에 사용했던 invokeLater 함수와 관련이 있는지 물어볼 수 있습니까? 새 행을 선택한 후 행 색상이 변경되는 이유는 무엇입니까? 나는 그것을 다시 작성하려고 노력했다. (그리고 나는 sscce가 내 코드를 깨끗이하고 깊게 수정하도록 디버깅하는 훌륭한 방법이기도하다는 것을 알았다. 나는 20 개의 클래스들 사이에서 길을 잃었다. 녹색으로 올바르게 표시되지만 새 행을 선택한 후에도 계속 표시됩니다. 미안해. 내가 시간 낭비했다면, 이제는 내가 sscce를 배웠어. 그래서 다음번에 내가 확실히 사용할거야! – A7X

+1

@ A7X :'AbstractAction'은 스테로이드의'ActionListener'와 비슷합니다. 그것은 JButton에 리스너를 제공하고 몇 가지 다른 중요한 상태 필드와 기능을 제공합니다. 'SwingUtilities.invokeLater (...)'는 실행중인 코드가 Swing 이벤트 스레드 또는 EDT (이벤트 발송 스레드)에서 실행되도록 보장하는 데 사용됩니다. 이것은 쓰레드 안전성을 엄격히 위함이며, 실행되지 않는 코드와 아무 관련이 없습니다. –

+0

알았습니다. 또한 목록에서 페인트 칠을 사용하는 것으로 나타났습니다. 특히 다른 arraylist 내부에서 선택해야하는 모든 요소를 ​​넣었습니다. 내 코드가 예상대로 작동하지 않는 또 다른 이유라고 생각합니다.하지만 목록에서 단일 선택을 강요하면 이러한 일을 할 수 없습니다. 맞습니까? 아니면 getSelectedValueList 메소드에 영향을주지 않을 것인가? – A7X