Java actionPerformed 不适用于其他方法

Java actionPerformed not applying to other methods

下面是控件的初始化。

public void init(){
    ...
    c = new JComboBox();
    ....
    c.addActionListener(this);

    p2 = new JPanel();
    vt = new Vector();
    ChannelList cl = new ChannelList();

    lchannels = new JList(vt);   
    lchannels.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    jp = new JScrollPane(lchannels);
    cl.createList();

    p2.add(jp);
    p2.setBorder(new TitledBorder("Channel Titles Available"));  
    p2.setLayout(new GridLayout(1,1,10,10));
}

actionPerformed() 方法的一部分应该确定来自 JCombobox 的选择,并将正确的对象放入 JList。

@Override
public void actionPerformed(ActionEvent e) {
    JComboBox c = (JComboBox)e.getSource();
    String genre = (String)c.getSelectedItem();
    System.out.println(genre);

    vt = new Vector();
    ChannelList cl = new ChannelList();

    lchannels = new JList(vt);   
    lchannels.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    jp = new JScrollPane(lchannels);
    cl.createList();

    for(int i =0; i < cl.chList.length; i++){
        char chGenre = cl.chList[i].getChGenre();
        switch(genre){
        case "All Genres":
            vt.add(cl.chList[i].getChTitle());
            break;
        case "Entertainment":
            if(chGenre == 'e')
                vt.add(cl.chList[i].getChTitle());
            break;
        }
    }
}

这是 ChannelList 的一部分:

public void createList()
{

    chList = new ChannelInfo[19];

    chList[0] = new ChannelInfo("BBC Canada",3.99, 5.99,'e',"bbccan.jpg");
    chList[1] = new ChannelInfo("Bloomberg TV",3.99, 5.99,'n',"bloom.jpg");
    ...
}

在运行程序中没有错误信息。打印字符串的 actionPerformed 的第一部分工作正常(无用)。 但是,JList 中没有显示任何结果。

为了更清楚,这里是整个文件:

import javax.swing.*;
import java.awt.*;
import java.text.*;
import java.util.Vector;
import java.util.*;
import java.awt.event.*;
import javax.swing.border.*;
import java.util.*; 

public class AS4Temp extends JApplet implements ItemListener, ActionListener{
JPanel p,p1,p2;

JComboBox c;
JList lchannels;
JScrollPane jp;
Vector vt;
Container con;

public void init(){
    p = new JPanel();
    p.setLayout(new GridLayout(3,3,10,10));

    //Genre
    p1 = new JPanel();
    c = new JComboBox();
    c.addItem("Please Select Genre of Channel");
    c.addItem("All Genres");
    c.addItem("Entertainment");
    c.addItem("Movie");
    c.addItem("News/Business");
    c.addItem("Sci-Fi");
    c.addItem("Sports");

    c.addActionListener(this);

    p1.add(c);

    p1.setLayout(new FlowLayout());
    p1.setBorder(new TitledBorder("Channel Genre"));

    //Channels

    p2 = new JPanel();
    vt = new Vector();
    ChannelList cl = new ChannelList();

    lchannels = new JList(vt);   
    lchannels.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    jp = new JScrollPane(lchannels);
    cl.createList();
    /*
    for(int i =0; i < cl.chList.length; i++){
        char chGenre = cl.chList[i].getChGenre();
        if(chGenre == 'e')
        vt.add(cl.chList[i].getChTitle());
    }*/
    p2.add(jp);
    p2.setBorder(new TitledBorder("Channel Titles Available"));  
    p2.setLayout(new GridLayout(1,1,10,10));

    //all panels
    p.add(p1);
    p.add(p2);

    con = getContentPane();
    con.add(p);
}

@Override
public void actionPerformed(ActionEvent e) {
    // TODO Auto-generated method stub
    JComboBox c = (JComboBox)e.getSource();
    String genre = (String)c.getSelectedItem();
    System.out.println(genre);

    ChannelList cl = new ChannelList();
    cl.createList();

    switch(genre){
    case "All Genres":
        for(int i =0; i < cl.chList.length; i++){
            char chGenre = cl.chList[i].getChGenre();
            vt.add(cl.chList[i].getChTitle());
        }
        break;
    case "Entertainment":
        for(int i =0; i < cl.chList.length; i++){
            char chGenre = cl.chList[i].getChGenre();
            if(chGenre == 'e')
                vt.add(cl.chList[i].getChTitle());
        }
        break;
    }

    /*
    for(int i =0; i < cl.chList.length; i++){
        char chGenre = cl.chList[i].getChGenre();
        switch(genre){
        case "All Genres":
            vt.add(cl.chList[i].getChTitle());
            break;
        case "Entertainment":
            if(chGenre == 'e')
                vt.add(cl.chList[i].getChTitle());
            break;
            }
        }*/
    }
}

问题是您要在 actionPerformed() 上添加一个新的 JList 而您还没有将列表添加到容器中。

lchannels = new JList(vt);   

您不需要在选择时添加新列表,您只需在选择时更新列表模型本身。

我是根据部分信息猜测的,但我看到您创建了新组件,包括新的 JList 和新的 JScrollPane:

lchannels = new JList(vt);   
lchannels.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jp = new JScrollPane(lchannels);

但是我没有看到 JScrollPane 被添加到任何东西中,所以显示 none 是有道理的。

看来您可能想要以非常不同的方式进行处理,而不是创建 new JList()new JScrollPane(...) 您可能想要创建一个新的 JList 模型并设置 existing JList 与这个新模型,或者只是更改现有 JList 模型所持有的数据。

考虑在您的 actionPerformed 方法中创建一个 DefaultListModelField 对象,比如说调用 listModel, callingaddElement(...)` 以用数据填充它,然后调用

myList.setModel(listModel);

在您现有的和显示的 JList 上。


例如,这是我的 minimal example program, or MCVE:

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

public class Mcve extends JPanel {
   private static final String[] DATA = {"One", "Two", "Three", "Four", "Five"};

   private DefaultComboBoxModel<String> comboModel = new DefaultComboBoxModel<>();
   private JComboBox<String> comboBox = new JComboBox<>(comboModel);

   private DefaultListModel<String> listModel = new DefaultListModel<>();
   private JList<String> list = new JList<>(listModel);

   public Mcve() {
      list.setPrototypeCellValue(String.format("%30s", " "));
      list.setVisibleRowCount(10);;

      // fill combo box's model with a bunch of junk
      for (int i = 0; i < 10; i++) {
         for (int j = 0; j < DATA.length; j++) {
            String text = DATA[j] + " " + i;
            comboModel.addElement(text);
         }
      }

      Action buttonAction = new ButtonAction("Transfer Data");
      comboBox.addActionListener(buttonAction);

      add(comboBox);
      add(new JScrollPane(list, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));
      add(new JButton(buttonAction));
   }

   private class ButtonAction extends AbstractAction {
      public ButtonAction(String name) {
         super(name);
         int mnemonic = (int) name.charAt(0);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         Object selection = comboBox.getSelectedItem();
         if (selection != null) {
            listModel.addElement(selection.toString());
         }
      }
   }

   private static void createAndShowGui() {
      Mcve mainPanel = new Mcve();

      JFrame frame = new JFrame("Mcve");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

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

您正在使用 Vector 代替列表模型,并且您似乎假设稍后在您的程序中更改 Vector 将更改 JList -- 但它不会。取而代之的是去掉那个 Vector,vt,然后再次按照我的建议做——使用 DefaultListModel 代替它。例如,请参阅下面的代码更改。更改标有 // !! 条评论:

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

public class AS4Temp extends JApplet implements ActionListener {
   JPanel p, p1, p2;

   JComboBox c;
   JList lchannels;
   JScrollPane jp;
   // !! Vector vt;
   private DefaultListModel<String> listModel = new DefaultListModel<>(); // !!
   Container con;

   public void init() {
      p = new JPanel();
      p.setLayout(new GridLayout(3, 3, 10, 10));

      // Genre
      p1 = new JPanel();
      c = new JComboBox();
      c.addItem("Please Select Genre of Channel");
      c.addItem("All Genres");
      c.addItem("Entertainment");
      c.addItem("Movie");
      c.addItem("News/Business");
      c.addItem("Sci-Fi");
      c.addItem("Sports");

      c.addActionListener(this);

      p1.add(c);

      p1.setLayout(new FlowLayout());
      p1.setBorder(new TitledBorder("Channel Genre"));

      // Channels

      p2 = new JPanel();
      // !! vt = new Vector();
      ChannelList cl = new ChannelList();

      // !! lchannels = new JList(vt);
      lchannels = new JList<>(listModel); // !!

      lchannels.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
      jp = new JScrollPane(lchannels);
      cl.createList();
      /*
       * for(int i =0; i < cl.chList.length; i++){ char chGenre =
       * cl.chList[i].getChGenre(); if(chGenre == 'e')
       * vt.add(cl.chList[i].getChTitle()); }
       */
      p2.add(jp);
      p2.setBorder(new TitledBorder("Channel Titles Available"));
      p2.setLayout(new GridLayout(1, 1, 10, 10));
      // price

      // all panels
      p.add(p1);
      p.add(p2);

      con = getContentPane();
      con.add(p);
   }

   @Override
   public void actionPerformed(ActionEvent e) {
      JComboBox c = (JComboBox) e.getSource();
      String genre = (String) c.getSelectedItem();
      System.out.println(genre);

      ChannelList cl = new ChannelList();
      cl.createList();

      switch (genre) {
      case "All Genres":
         for (int i = 0; i < cl.chList.length; i++) {
            char chGenre = cl.chList[i].getChGenre();
            // !! vt.add(cl.chList[i].getChTitle());
            listModel.addElement(cl.chList[i].getChTitle()); // !!
         }
         break;
      case "Entertainment":
         for (int i = 0; i < cl.chList.length; i++) {
            char chGenre = cl.chList[i].getChGenre();
            if (chGenre == 'e')
               // !! vt.add(cl.chList[i].getChTitle());
               listModel.addElement(cl.chList[i].getChTitle()); // !!
         }
         break;
      }

   }
}

// !! added to make your code compilable
// !! in the future, please don't force us to do this kludge
class ChannelList {

   public Channel[] chList;

   public ChannelList() {
      createList();
   }

   public void createList() {
      chList = new Channel[5];
      chList[0] = new Channel("Foobar1", 'e');
      chList[1] = new Channel("Foobar2", 'e');
      chList[2] = new Channel("Foobar3", 'e');
      chList[3] = new Channel("Foobar4", 'e');
      chList[4] = new Channel("Foobar5", 'e');
   }

}

// !! added to make your code compilable
// !! in the future, please don't force us to do this kludge
class Channel {
   private String title;
   private char genre;

   public Channel(String title, char genre) {
      this.title = title;
      this.genre = genre;
   }

   public char getChGenre() {
      return genre;
   }

   public String getChTitle() {
      return title;
   }

   @Override
   public String toString() {
      return "Channel [title=" + title + ", genre=" + genre + "]";
   }

}