문제

Java Swing에서 각각 체크박스가 있는 항목 목록을 갖는 가장 좋은 방법은 무엇입니까?

즉.텍스트와 체크박스가 있는 항목이 있는 JList가 있습니까?

도움이 되었습니까?

해결책

사용자 정의 만들기 ListCellRenderer 그리고 그것을 JList.

이 관습 ListCellRenderer 반환해야합니다 JCheckbox 구현에 getListCellRendererComponent(...) 방법.

하지만 이것은 JCheckbox 편집할 수 없으며 화면에 간단한 페인트를 칠하는 것은 사용자가 선택할 수 있습니다. JCheckbox '체크'를 선택해야 합니다.

예를 들어, 행이 선택되면 선택되었음을 표시합니다(매개변수 isSelected) 그러나 이렇게 하면 선택 사항이 변경되면 확인 상태가 유지되지 않습니다.아래 데이터를 참조하여 확인되었음을 보여주는 것이 좋습니다. ListModel, 그러나 데이터의 확인 상태를 변경하는 방법을 구현하고 변경 사항을 JList 다시 칠할 것.

나중에 필요하면 샘플 코드를 게시하겠습니다.

ListCellRenderer

다른 팁

멋진 대답은 이것이다 CheckBoxList.Telcontar의 답변을 구현합니다(3년 전이지만 :)...Java 1.6에서 문제 없이 사용하고 있습니다.나는 또한 addCheckbox 다음과 같은 방법이 있습니다(분명히 더 짧을 수 있으며 한동안 Java를 사용하지 않았습니다).

public void addCheckbox(JCheckBox checkBox) {
    ListModel currentList = this.getModel();
    JCheckBox[] newList = new JCheckBox[currentList.getSize() + 1];
    for (int i = 0; i < currentList.getSize(); i++) {
        newList[i] = (JCheckBox) currentList.getElementAt(i);
    }
    newList[newList.length - 1] = checkBox;
    setListData(newList);
}

나는 Jidesoft 관련 데모를 시험해 보았습니다. CheckBoxList 몇 가지 문제(작동하지 않는 동작)가 발생했습니다.문제가 발견되면 이 답변을 수정하겠습니다. CheckBoxList 에 연결했습니다.

나는 아마도 다음을 사용하려고 할 것입니다. JTable 보다는 JList 그리고 체크박스의 기본 렌더링이 다소 보기 흉하기 때문에 아마도 사용자 정의를 적용하려고 할 것입니다. 테이블모델, 셀렌더러 그리고 셀에디터 부울 값을 나타냅니다.물론 나는 이것이 이미 수십억 번 수행되었다고 생각합니다.썬은 좋은 예.

그냥 구현하세요 ListCellRenderer

public class CheckboxListCellRenderer extends JCheckBox implements ListCellRenderer {

    public Component getListCellRendererComponent(JList list, Object value, int index, 
            boolean isSelected, boolean cellHasFocus) {

        setComponentOrientation(list.getComponentOrientation());
        setFont(list.getFont());
        setBackground(list.getBackground());
        setForeground(list.getForeground());
        setSelected(isSelected);
        setEnabled(list.isEnabled());

        setText(value == null ? "" : value.toString());  

        return this;
    }
}

렌더러를 설정하고

JList list = new JList();
list.setCellRenderer(new CheckboxListCellRenderer());

이는 다음과 같은 결과를 가져올 것입니다

CheckboxListCellRenderer example

자세한 내용은 사용자 정의 스윙 구성 요소 렌더러.

추신:라디오 요소를 원한다면 그냥 바꾸십시오. extends JCheckbox ~와 함께 extends JRadioButton.

Java 7 이상을 위한 더 나은 솔루션

나는 이 질문을 우연히 발견했고 일부 답변이 꽤 오래되고 구식이라는 것을 깨달았습니다.요즘에는 JList가 일반적이므로 더 나은 솔루션이 있습니다.

일반 JCheckBoxList에 대한 내 솔루션은 다음과 같습니다.

import java.awt.Component;

import javax.swing.*;
import javax.swing.border.*;

import java.awt.event.*;

@SuppressWarnings("serial")
public class JCheckBoxList extends JList<JCheckBox> {
  protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);

  public JCheckBoxList() {
    setCellRenderer(new CellRenderer());
    addMouseListener(new MouseAdapter() {
      public void mousePressed(MouseEvent e) {
        int index = locationToIndex(e.getPoint());
        if (index != -1) {
          JCheckBox checkbox = (JCheckBox) getModel().getElementAt(index);
          checkbox.setSelected(!checkbox.isSelected());
          repaint();
        }
      }
    });
    setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
  }

  public JCheckBoxList(ListModel<JCheckBox> model){
    this();
    setModel(model);
  }

  protected class CellRenderer implements ListCellRenderer<JCheckBox> {
    public Component getListCellRendererComponent(
        JList<? extends JCheckBox> list, JCheckBox value, int index,
        boolean isSelected, boolean cellHasFocus) {
      JCheckBox checkbox = value;

      //Drawing checkbox, change the appearance here
      checkbox.setBackground(isSelected ? getSelectionBackground()
          : getBackground());
      checkbox.setForeground(isSelected ? getSelectionForeground()
          : getForeground());
      checkbox.setEnabled(isEnabled());
      checkbox.setFont(getFont());
      checkbox.setFocusPainted(false);
      checkbox.setBorderPainted(true);
      checkbox.setBorder(isSelected ? UIManager
          .getBorder("List.focusCellHighlightBorder") : noFocusBorder);
      return checkbox;
    }
  }
}

JCheckBox 목록을 동적으로 추가하려면 자신만의 ListModel을 생성하거나 DefaultListModel을 추가해야 합니다.

DefaultListModel<JCheckBox> model = new DefaultListModel<JCheckBox>();
JCheckBoxList checkBoxList = new JCheckBoxList(model);

그만큼 기본목록모델 일반적이므로 JAVA 7 API에서 지정한 메소드를 사용할 수 있습니다. 여기 이와 같이:

model.addElement(new JCheckBox("Checkbox1"));
model.addElement(new JCheckBox("Checkbox2"));
model.addElement(new JCheckBox("Checkbox3"));

누군가가 이미 필요한 위젯이나 유틸리티를 구현했을 가능성이 높습니다.대규모 OSS 커뮤니티의 이점 중 일부입니다.정말로 스스로 하고 싶지 않다면 바퀴를 재발명할 필요가 없습니다.이 경우 CellRenderers 및 Editors에 대한 좋은 학습 연습이 될 것입니다.

내 프로젝트는 JIDE를 통해 큰 성공을 거두었습니다.원하는 구성 요소인 확인란 목록은 JIDE 공통 계층(OSS이고 java.net에서 호스팅됨)에 있습니다.상업용 자료도 좋지만 필요하지는 않습니다.

http://www.jidesoft.com/products/oss.htm https://jide-oss.dev.java.net/

1개의 열이 있는 GridLayout이 있는 JPanel을 사용하는 것이 좋습니다.JPanel에 checkBox를 추가하고 JPanel을 JScrollPane의 데이터 소스로 설정합니다.선택한 CheckBox를 가져오려면 JPanel의 getComponents()를 호출하여 CheckBox를 가져오면 됩니다.

다음은 Rawa의 JCheckBoxList에 약간의 추가 사항입니다.스페이스바를 사용해 선택할 수 있는 기능이 추가됩니다.여러 항목을 선택한 경우 첫 번째 항목의 값이 모두 반전되어 설정됩니다.

        addKeyListener(new KeyAdapter() {
        @Override
        public void keyPressed(KeyEvent e) {
            int index = getSelectedIndex();
            if (index != -1 && e.getKeyCode() == KeyEvent.VK_SPACE) {
                boolean newVal = !((JCheckBox) (getModel()
                        .getElementAt(index))).isSelected();
                for (int i : getSelectedIndices()) {
                    JCheckBox checkbox = (JCheckBox) getModel()
                            .getElementAt(i);
                    checkbox.setSelected(newVal);
                    repaint();
                }
            }
        }
        });

Swing의 모든 집합 구성 요소, 즉 JTable, JTree 또는 JComboBox와 같은 다른 구성 요소로 구성된 구성 요소는 고도로 사용자 정의될 수 있습니다.예를 들어 JTable 구성 요소는 일반적으로 JLabel 구성 요소의 그리드를 표시하지만 JButton, JTextField 또는 기타 JTable도 표시할 수도 있습니다.그러나 기본이 아닌 개체를 표시하도록 이러한 집계 구성 요소를 가져오는 것은 쉬운 부분입니다.스윙의 구성 요소를 "렌더러"및 "편집자"로 분리하기 때문에 키보드 및 마우스 이벤트에 올바르게 응답하는 것은 훨씬 어려운 작업입니다. 이 분리는 (내 의견으로는) 디자인 선택이 좋지 않았으며 스윙 구성 요소를 확장하려고 할 때만 문제를 복잡하게하는 역할을합니다.

무슨 뜻인지 보려면 레이블 대신 확인란을 표시하도록 Swing의 JList 구성 요소를 향상해 보십시오.Swing 철학에 따르면 이 작업에는 두 가지 인터페이스를 구현해야 합니다.ListCellRenderer(체크박스 그리기용) 및 CellEditor(체크박스의 키보드 및 마우스 이벤트 처리용)ListCellRenderer 인터페이스를 구현하는 것은 충분히 쉽지만 CellEditor 인터페이스는 다소 서투르고 이해하기 어려울 수 있습니다.이 특별한 경우에는 다음 코드와 같이 CellEditor를 완전히 잊어버리고 입력 이벤트를 직접 처리하는 것이 좋습니다.

import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;

public class CheckBoxList extends JList
{
   protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);

   public CheckBoxList()
   {
      setCellRenderer(new CellRenderer());

      addMouseListener(new MouseAdapter()
         {
            public void mousePressed(MouseEvent e)
            {
               int index = locationToIndex(e.getPoint());

               if (index != -1) {
                  JCheckBox checkbox = (JCheckBox)
                              getModel().getElementAt(index);
                  checkbox.setSelected(
                                     !checkbox.isSelected());
                  repaint();
               }
            }
         }
      );

      setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
   }

   protected class CellRenderer implements ListCellRenderer
   {
      public Component getListCellRendererComponent(
                    JList list, Object value, int index,
                    boolean isSelected, boolean cellHasFocus)
      {
         JCheckBox checkbox = (JCheckBox) value;
         checkbox.setBackground(isSelected ?
                 getSelectionBackground() : getBackground());
         checkbox.setForeground(isSelected ?
                 getSelectionForeground() : getForeground());
         checkbox.setEnabled(isEnabled());
         checkbox.setFont(getFont());
         checkbox.setFocusPainted(false);
         checkbox.setBorderPainted(true);
         checkbox.setBorder(isSelected ?
          UIManager.getBorder(
           "List.focusCellHighlightBorder") : noFocusBorder);
         return checkbox;
      }
   }
}

여기에서는 목록 상자에서 마우스 클릭을 가로채서 해당 확인란에 대한 클릭을 시뮬레이션합니다.그 결과는 CellEditor 인터페이스를 사용하는 동등한 구성 요소보다 더 간단하고 작은 "CheckBoxList" 구성 요소입니다.클래스를 사용하려면 클래스를 인스턴스화한 다음 setListData를 호출하여 JCheckBox 객체 배열(또는 JCheckBox 객체의 하위 클래스)을 전달하면 됩니다.이 구성 요소의 확인란은 키 누르기에 응답하지 않습니다(예:스페이스바), 필요한 경우 언제든지 고유한 키 리스너를 추가할 수 있습니다.

원천: DevX.com

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top