2016-07-15 5 views
2

Я пишу графический интерфейс Java. У меня есть несколько предустановленных JComboBoxes и чтобы они могли отличать их друг от друга, я хочу расширить класс и добавить переменную enum, которая может помочь мне отличить их друг от друга.Как расширить класс JComboBox?

Вот MCVE из двух стандартных JComboBoxes:

import java.awt.BorderLayout; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.DefaultComboBoxModel; 
import javax.swing.JButton; 
import javax.swing.JComboBox; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class XComboBoxMCVE extends JPanel { 

    private JComboBox tfComboBox; 
    private JComboBox ynComboBox; 
    private JComponent[] components; 

    public XComboBoxMCVE() { 
     setLayout(new BorderLayout()); 

     JPanel comboPanel = new JPanel(new GridLayout(0, 1, 5, 5)); 

     Boolean[] trueFalse = { true, false }; 
     DefaultComboBoxModel tfModel = new DefaultComboBoxModel(trueFalse); 
     tfComboBox = new JComboBox(tfModel); 

     String[] yesNo = { "Yes", "No" }; 
     DefaultComboBoxModel ynModel = new DefaultComboBoxModel(yesNo); 
     ynComboBox = new JComboBox(ynModel); 

     components = new JComponent[] { tfComboBox, ynComboBox }; 

     JButton printSelection = new JButton("Print Type"); 
     printSelection.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       for (JComponent component : components) { 
        // I also have other components in component in program, 
        // therefore this usage.. 
        if (component instanceof JComboBox) { 
         JComboBox temp = (JComboBox) component; 
         System.out.println("Printing selection: " + temp.getSelectedItem().toString()); 
         // if (temp.getBoxType() == BoxType.Company){ 
         // System.out.println("Companies say: " + 
         // temp.getSelectedItem().toString()); 
         // } else if(temp.getBoxType() == BoxType.Device){ 
         // System.out.println("Devices are: " + 
         // temp.getSelectedItem().toString()); 
         // } 
        } 
       } 
      } 
     }); 

     JPanel buttonPane = new JPanel(new GridLayout(0, 1, 5, 5)); 
     buttonPane.add(printSelection); 

     comboPanel.add(tfComboBox); 
     comboPanel.add(ynComboBox); 

     add(comboPanel, BorderLayout.CENTER); 
     add(buttonPane, BorderLayout.PAGE_END); 
    } 

    public static void createAndShowGUI(){ 
     JFrame frame = new JFrame("MCVE"); 
     frame.setLayout(new BorderLayout()); 

     XComboBoxMCVE pane = new XComboBoxMCVE(); 

     frame.add(pane, BorderLayout.CENTER); 
     frame.setResizable(false); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       createAndShowGUI(); 
      } 
     }); 
    } 
} 

class XComboBox extends JComboBox { 
    BoxType type; 

    public XComboBox(BoxType type) { 
     this.type = type; 
    } 

    public void setBoxType(BoxType type) { 
     this.type = type; 
    } 

    public BoxType getBoxType() { 
     return this.type; 
    } 

    public enum BoxType { 
     Model, Company, Device 
    } 
} 

Как пример выше, иллюстрирующий, нет никакого способа для меня отчетливый два JComboBoxes друг от друга, когда пользователь нажимает на кнопку. Примером использования BoxType было бы то, что один BoxType напечатал один тип сообщения, а другой BoxType напечатал другое сообщение. Например:

if(temp.getBoxType() == BoxType.Device){ 
    System.out.println("The devices are: " + temp.getSelectedItem().toString()); 
} else if(temp.getBoxType() == BoxType.Company){ 
    System.out.println("The companies say: " + temp.getSelectedItem().toString()); 
} 

Однако я наткнулся на проблему с конструктором, который я пытаюсь использовать подобное тому, что я сделал с JComboBox и вводом DefaultComboBoxModel, который я до сих пор не реализован в XComboBox классе.

Вопрос

Как я могу изменить XComboBox класс, так что я могу дать ему DefaultComboBoxModel при построении элемента?

Я хочу быть в состоянии сделать это:

ynComboBox = new XComboBox(tfModel); 
ynComboBox.setBoxType(BoxType.Device); 

Спасибо за любую помощь и или руководства!

+2

1. Почему вы простирающийся JComboBox в первую очередь, как вы, кажется, не будет изменять какие-либо врожденные модели поведения? 2. Я не уверен, что вы на самом деле застряли или что представляет собой BoxType. 3. Подумайте о создании реального кода [mcve], кода, который мы можем запустить. –

+0

Ничего себе .. да. Извините .. Исправит все как можно скорее. По какой-то причине он сохранил старый заголовок. – Zeliax

+0

Выполнено. Не стесняйтесь спрашивать, что-то непонятно. MCVE не использует XComboBox, но я сохранил их там, поскольку они являются частью вопроса. – Zeliax

ответ

2

Вам необходимо связать JComboBox с BoxType, и одним из лучших способов связать два объекта является использование карты, здесь Map<BoxType, JComboBox>. После того, как вы это сделали, вы можете легко извлечь с помощью combo box, какой выбор. Опять же, я бы не стал расширять JCombo. Например, мой MCVE:

import java.awt.BorderLayout; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.ArrayList; 
import java.util.Collections; 
import java.util.EnumMap; 
import java.util.List; 
import java.util.Map; 

import javax.swing.BorderFactory; 
import javax.swing.DefaultComboBoxModel; 
import javax.swing.JButton; 
import javax.swing.JComboBox; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class XComboBoxMCVE extends JPanel { 
    private static final long serialVersionUID = 1L; 
    private Map<BoxType, JComboBox<String>> comboMap = new EnumMap<>(BoxType.class); 

    public XComboBoxMCVE() { 
     setLayout(new BorderLayout()); 
     JPanel comboPanel = new JPanel(new GridLayout(0, 1, 5, 5)); 

     // just for example 
     String[] modelItemsArray = {"Model Item A", "Model Item B", "Model Item C", "Model Item D"}; 
     BoxItems modelItems = new BoxItems(BoxType.MODEL, modelItemsArray); 
     String[] CompanyItemsArray = {"Company Item A", "Company Item B", "Company Item C", "Company Item D"}; 
     BoxItems companyItems = new BoxItems(BoxType.COMPANY, CompanyItemsArray); 
     String[] deviceItemsArray = {"Device Item A", "Device Item B", "Device Item C", "Device Item D"}; 
     BoxItems deviceItems = new BoxItems(BoxType.DEVICE, deviceItemsArray); 

     createAndPlaceComboBox(BoxType.MODEL, modelItems, comboPanel); 
     createAndPlaceComboBox(BoxType.COMPANY, companyItems, comboPanel); 
     createAndPlaceComboBox(BoxType.DEVICE, deviceItems, comboPanel); 

     JButton printSelection = new JButton("Print Type"); 
     printSelection.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       for (BoxType boxType : BoxType.values()) { 
        // use the Map to get the appropriate JComboBox 
        JComboBox<String> combo = comboMap.get(boxType); 
        String selection = (String) combo.getSelectedItem(); 
        if (selection == null) { 
         selection = "NONE"; 
        } 
        String text = String.format("Selection for box type %s: %s: ", 
          boxType.getText(), selection); 
        System.out.println(text); 
       } 
      } 
     }); 

     JPanel buttonPane = new JPanel(new GridLayout(0, 1, 5, 5)); 
     buttonPane.add(printSelection); 

     add(comboPanel, BorderLayout.CENTER); 
     add(buttonPane, BorderLayout.PAGE_END); 
    } 

    private void createAndPlaceComboBox(BoxType boxType, BoxItems boxItems, JPanel panel) { 
     String[] items = boxItems.getItems().toArray(new String[] {}); 
     DefaultComboBoxModel<String> comboModel = new DefaultComboBoxModel<>(items); // create model 
     JComboBox<String> combo = new JComboBox<>(comboModel); // crteate combo 
     comboMap.put(boxType, combo); // put combo into Map 

     JPanel wrapPanel = new JPanel(new BorderLayout()); // wrapper panel that has a title border 
     wrapPanel.add(combo); 
     wrapPanel.setBorder(BorderFactory.createTitledBorder(boxType.getText() + " Items")); 
     panel.add(wrapPanel); 
    } 

    public static void createAndShowGUI() { 
     JFrame frame = new JFrame("MCVE"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     XComboBoxMCVE pane = new XComboBoxMCVE(); 
     frame.add(pane, BorderLayout.CENTER); 
     frame.setResizable(false); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       createAndShowGUI(); 
      } 
     }); 
    } 
} 

// A better enum, one not inside of an unnecessary class 
enum BoxType { 
    MODEL("Model"), COMPANY("Company"), DEVICE("Device"); 
    private String text; 

    private BoxType(String text) { 
     this.text = text; 
    } 

    public String getText() { 
     return text; 
    } 
} 

// class to associate BoxType with possible items associated with it 
class BoxItems { 
    private BoxType boxType; 
    private List<String> items = new ArrayList<>(); 

    public BoxItems(BoxType boxType) { 
     this.boxType = boxType; 
    } 

    public BoxItems(BoxType boxType, String[] itemsArray) { 
     this(boxType); 
     for (String item : itemsArray) { 
      items.add(item); 
     } 
    } 

    public void addItem(String item) { 
     items.add(item); 
    } 

    public BoxType getBoxType() { 
     return boxType; 
    } 

    public List<String> getItems() { 
     // unmodifiable so that can't be changed outside of this class 
     return Collections.unmodifiableList(items); 
    } 
} 
Смежные вопросы