java 添加到带有 ActionListener 的 JList 并在添加后刷新 GUI 框架

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4396489/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 06:11:32  来源:igfitidea点击:

Adding to a JList with an ActionListener and refresihing GUI frame after adding

javauser-interfacejlistactionlistener

提问by Jacob

I am working on a project (yes it is for school, no I don't want anyone to write it for me. I have too much pride!) using some of the GUI components of java. It is still in a fairly rough stage, and a single thing is keeping me from getting this finished. I try not to ask for help unless I really need it because usually when I do ask it turns out to be a simple mistake, so if that is the case here, take it easy on me. Anyway, so on to the code. This is a group project so some of my comments are to my partner. I would ask them, but it is 4am... Anyway, here it is. Not sure why it is in all these separate boxes. The listener I am messing with is ActionPerformed, near the bottom. I thank you graciously in advance for any help.

我正在做一个项目(是的,它是学校用的,不,我不想让任何人为我写它。我太骄傲了!)使用 java 的一些 GUI 组件。它仍处于相当艰难的阶段,有一件事使我无法完成它。除非我真的需要帮助,否则我尽量不寻求帮助,因为通常当我提出要求时,结果证明是一个简单的错误,所以如果这里是这种情况,请放轻松。无论如何,等等到代码。这是一个小组项目,所以我的一些评论是给我的合作伙伴的。我会问他们,但现在是凌晨 4 点……无论如何,就在这里。不知道为什么它在所有这些单独的盒子里。我惹恼的听众是 ActionPerformed,靠近底部。我提前感谢您的任何帮助。

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;


public class GUI extends JFrame
{
  private JPanel panel;
  private JFrame frame;
  private JTextArea text;
  private MP3List list = new MP3List();
  private JList songList;
  private JScrollPane scrollList;
  private JMenuBar menuBar;
  private JMenu menu;
  private JMenuItem menuAdd;
  private String[] songs;
  private static String mp3msg = "Project 2: MP3 Tracker"; // Header for JOptionPane


  public GUI()
  {
    super("mp3");
    panel = new JPanel();
    createGUI();
    add(panel);
  }


  public void createGUI()
  {


//This creates the frame(createGUI)
    frame = new JFrame();

//Here, I made an array of the song titles and gave them to a JList
//for display. Do you think we should sort the songs?
    songs = new String[list.getSize()];
    for (int i = 0; i < list.getSize(); i++)
    {
      songs[i] = list.get(i).getSongTitle();
    }
    songList = new JList(songs);

//Set the selection mode to single as I want to fill in fields with info on a clicked song. More on
//that to come.
    songList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
//Made a scroll bar(vertical and horizontal just in case)
    scrollList = new JScrollPane(songList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
        JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);


    text = new JTextArea(30, 30);
    text.setText("This section will hold information about songs and somesuch.");


    menuBar = new JMenuBar();
    menu = new JMenu("File");
    menuAdd = new JMenuItem("Add Song");
    menuAdd.addActionListener(new menuListener());
    menu.add(menuAdd);
    menuBar.add(menu);


    frame.setLayout(new Border());

    songList.addListSelectionListener(new ListSelectionListener()
    {
      public void valueChanged(ListSelectionEvent e)
      {

        int selectedVar;
        selectedVar = songList.getSelectedIndex();
        text.setText(("Song Title: " + list.get(selectedVar).getSongTitle())
            + ("\nArtist: " + list.get(selectedVar).getArtistName())
            + ("\nPlayback Time: " + list.get(selectedVar).getPlayBackTime())
            + ("  ||  Cost: " + list.get(selectedVar).getDownloadCost())
            + ("  ||  Size: " + list.get(selectedVar).getFileSize()));
      }
    });

  }


  public class Border extends JFrame implements LayoutManager
  {
    private static final long serialVersionUID = 1L;
    private final int WINDOW_WIDTH = 400;
    private final int WINDOW_HEIGHT = 300;

    public Border()
    {
      super("MP3 Editor");
      setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      add(scrollList, BorderLayout.CENTER);
      add(text, BorderLayout.SOUTH);
      setJMenuBar(menuBar);
      setVisible(true);
    }


    @Override
    public void addLayoutComponent(String name, Component comp)
    {
      // TODO Auto-generated method stub


    }

    @Override
    public void layoutContainer(Container parent)
    {
      // TODO Auto-generated method stub

    }

    @Override
    public Dimension minimumLayoutSize(Container parent)
    {
      // TODO Auto-generated method stub
      return null;
    }

    @Override
    public Dimension preferredLayoutSize(Container parent)
    {
      // TODO Auto-generated method stub
      return null;
    }

    @Override
    public void removeLayoutComponent(Component comp)
    {
      // TODO Auto-generated method stub

    }
  }

  public class menuListener extends JMenuItem implements ActionListener
  {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

/*public menuListener()
{
  menuItem.addActionListener(this);
}*/

    public void actionPerformed(ActionEvent e)
    {
      MP3 aSong = getInfo();
      list.add(aSong);
      songs = new String[list.getSize()];
      for (int i = 0; i < list.getSize(); i++)
      {
        songs[i] = list.get(i).getSongTitle();
      }
      songList = new JList(songs);
      scrollList = new JScrollPane(songList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
          JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
      int index = 0;
      songList.setSelectedIndex(index);
      songList.ensureIndexIsVisible(index);
    }

  }

  /**
   * Input one set of MP3 file information and produce a report <br>
   * <p/>
   * <hr>
   * Date created: Sep 22, 2010 <br>
   * Date last modified: Sep 22, 2010 <br>
   * <p/>
   * <hr>
   */

  public static MP3 getInfo()
  {

    // Gather all information using JOptionPane
    String title = JOptionPane.showInputDialog(null,
        "Enter Title: ",
        mp3msg,
        JOptionPane.QUESTION_MESSAGE);
    String artist = JOptionPane.showInputDialog(null,
        "Enter Artist: ",
        mp3msg,
        JOptionPane.QUESTION_MESSAGE);
    int seconds = Integer.parseInt(JOptionPane.showInputDialog(null,
        "Enter playback time in seconds: ",
        mp3msg,
        JOptionPane.QUESTION_MESSAGE));
    double cost = Double.parseDouble(JOptionPane.showInputDialog(null,
        "Enter download cost: ",
        mp3msg,
        JOptionPane.QUESTION_MESSAGE));
    double size = Double.parseDouble(JOptionPane.showInputDialog(null,
        "Enter file size in megabytes (MB): ",
        mp3msg,
        JOptionPane.QUESTION_MESSAGE));
    MP3 asong = new MP3(title, artist, seconds, cost, size);
    return asong;
  }


}

回答by BoffinBrain

There are a number of little issues with your code, but I think the most important one for you is the part where you add a new MP3 in the action listener (the part you said you want help with). Here, you create a brand new JListand you overwrite the previous JList, and you create a new scroll pane for it, but you don'tadd the new JList to your GUI so the old one remains (and so you never see any changes).

您的代码存在许多小问题,但我认为对您来说最重要的是在动作侦听器中添加新 MP3 的部分(您说需要帮助的部分)。在这里,您创建了一个全新的JList并且覆盖了之前的JList,并为其创建了一个新的滚动窗格,但是您没有将新的 JList 添加到您的 GUI 中,因此旧的 JList 仍然存在(因此您永远不会看到任何更改)。

Ideally, you should keep the same list throughout, and just update the contents. There are several ways to do that, but one of the easiest is to simply call songList.setListData(songs). Or, instead of creating an array of Strings, create a Vectorbecause JLists work with Vectors too.

理想情况下,您应该始终保持相同的列表,并且只更新内容。有几种方法可以做到这一点,但最简单的方法之一是简单地调用songList.setListData(songs). 或者,不是创建一个字符串数组,而是创建一个,Vector因为 JLists 也可以与 Vectors 一起使用。

Other issues you might want to look at:

您可能想查看的其他问题:

  • private JFrame frame;is never used.
  • Your class Borderis a JFramebut is also used as a LayoutManager, which is extremely confusing and wrong. You should get rid of that.
  • private JFrame frame;从不使用。
  • 你的类Border是 aJFrame但也用作 a LayoutManager,这是非常混乱和错误的。你应该摆脱它。

Personally, I'd recommend you rewrite the GUI from scratch. Here's a simple example with a working JList for you to examine:

就个人而言,我建议您从头开始重写 GUI。这是一个简单的示例,其中包含一个有效的 JList 供您检查:

package examples;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;

public class GUI extends JFrame {

    private final Vector<String> myVector = new Vector<String>();
    private final JList myList = new JList();

    public static void main(String... args) {
        new GUI().setVisible(true);
    }

    public GUI() {
        super("List");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());
        add(new JButton(new AddItemAction()), BorderLayout.NORTH);
        add(new JScrollPane(myList), BorderLayout.CENTER);
        pack();
    }

    private class AddItemAction extends AbstractAction {
        public AddItemAction() {
            super("Add Item");
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            String newItem = JOptionPane.showInputDialog("Add a new item:");

            if (newItem != null) {
                myVector.add(newItem);
                myList.setListData(myVector);
            }
        }
    }

}

回答by camickr

Read the JList API and follow the link to the secton in the Swing tutorial on "How to Use Lists" which gives a working examples of adding a value to a JList when a button is clicked. Compare you code with the working code to see what the difference is.

阅读 JList API 并点击 Swing 教程中有关“如何使用列表”的部分的链接,该部分提供了在单击按钮时向 JList 添加值的工作示例。将您的代码与工作代码进行比较,看看有什么不同。