repaint JPanel with every click at JList

2019-02-28 01:28发布

everytime i click on a JList item, i need to clear + refresh my current panel & load another panel, returned via method 'populateWithButtons()'. temp is an int variable that stores what was clicked at the JList. How do i rectify the following?

        list_1.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent evt) {

                //refresh + populate JPanel
                Food food = new Food();             
                JPanel panel2 = new JPanel();
                JPanel pane11 = new JPanel();


                panel2.add(panel1);
                panel1.validate();
                panel1.repaint();
                panel1.setBounds(153, 74, 281, 269);

                panel1.add(food.populateWithButtons(temp));             
                contentPane.add(panel2);
        }

3条回答
倾城 Initia
2楼-- · 2019-02-28 01:48

move validate() and repaint() after adding to contentPane as in that point it will be redrawed.

查看更多
Ridiculous、
3楼-- · 2019-02-28 01:56

Use correct architecture pattern - like MVC. Basic usage example you have here.

  • Then your MouseAdapter will update variable of selected item in model and refresh view with repaint() method (instead working directly on GUI).
  • The view will hold JPanel with override paint() method that shows content according to selected element in model.

You will thank me later. ;) In your approach you will lose flexibility and come back with another problem soon.

Bad way (but will work)

  • In your view create setter and getter for the desired panel.
  • In your MouseAdapter (or other listener) hold reference to that view.
  • In your mouseClicked() method create a new panel and then override old with setter.
查看更多
萌系小妹纸
4楼-- · 2019-02-28 02:00
  1. don't to use NullLayout

  2. add ListSelectionListener to JList instead of MouseListener, otherwise you would need to convert point from mouse to Item in JList

  3. use CardLayout instead of add, remove JPanels on runtime, then selection from ListSelectionListener (ListSelectionModel to SINGLE...) to switch prepared card (JPanel with some contents)

EDIT

enter image description here

.

enter image description here

.

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class CardlayoutTest {

    private Color[] colors = new Color[]{Color.BLACK, Color.RED, Color.GREEN, Color.BLUE};
    private JFrame frame = new JFrame();
    private JList list = new JList();
    private JPanel panel = new JPanel();
    private CardLayout card = new CardLayout();

    public CardlayoutTest() {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        panel.setLayout(card);
        Vector<String> items = new Vector<String>();
        for (int x = 0; x < colors.length; x++) {
            JPanel pnl = new JPanel(new BorderLayout());
            pnl.setBackground(colors[x]);
            panel.add(pnl, colors[x].toString());
            items.add(colors[x].toString());
        }
        list = new JList(items);
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        list.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                if (!e.getValueIsAdjusting()) {
                    String card = list.getSelectedValue().toString();
                    CardLayout cL = (CardLayout) (panel.getLayout());
                    cL.show(panel, card);
                }
            }
        });
        frame.add(new JScrollPane(list), BorderLayout.WEST);
        frame.add(panel);
        frame.setPreferredSize(new Dimension(400, 150));
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new CardlayoutTest();
            }
        });
    }
}
查看更多
登录 后发表回答