单击JmenuItem时更新边框标题

时间:2017-08-14 22:25:51

标签: java swing

我的问题有点复杂了,我试图在点击JMenuItem时更新Jpanel的borderTitle,我有3个类,A实现ActionListener,B是JPanel类,C是JFrame类,这里是什么我已经尝试过了

public class PanelTitle implements ActionListener{
     String title;
    public PanelTitle(){
    }                     
    @Override
    public void actionPerformed(ActionEvent ae){
         SedimentPanel sp = new SedimentPanel();
         sp.titledBorder.setTitle("SEDIMENT");

         sp.repaint();
         sp.revalidate();


    }
}

我在JFrame类中有这个

 velocityMenuItem.addActionListener(new PanelTitle());

这是我的JPanel类

public class SedimentPanel extends JPanel{
    public SedimentPanel(){
        super();
        initComponents();
        initPlaceHolders();
        setBorder(titledBorder); 

    }

    TitledBorder titledBorder = BorderFactory.createTitledBorder(null, "border title",TitledBorder.CENTER,TitledBorder.DEFAULT_POSITION);

}

请问当我点击JMenuItem时,我如何才能真正改变borderTitle? 这是我在框架类中引用它的方法,现在我得到一个Nullpointer Exception

public class FrameClass extends JFrame{
private static SedimentPanel sp;
    public FrameClass(SedimentPanel sp){
        this.sp = sp;}
}
public static void main(String args[]){
 FrameClass fc = new FrameClass(sp);
}

1 个答案:

答案 0 :(得分:4)

你在这里犯了一个基本错误:

public class PanelTitle implements ActionListener{
     String title;
    public PanelTitle(){
    }                     
    @Override
    public void actionPerformed(ActionEvent ae){
         SedimentPanel sp = new SedimentPanel(); // ********
         sp.titledBorder.setTitle("SEDIMENT");

         sp.repaint();
         sp.revalidate();
    }
}

新的SedimentPanel是一个全新的引用,并且调用它上面的方法对原始显示的对象没有任何影响。不要这样做,获得适当的参考并在其上调用方法。

public class PanelTitle implements ActionListener{
    String title;
    private SedimentPanel sp;

    public PanelTitle(SedimentPanel sp){  // pass in reference
        this.sp = sp;
    }

    @Override
    public void actionPerformed(ActionEvent ae){
         // SedimentPanel sp = new SedimentPanel(); // ******** NO
         // sp.titledBorder.setTitle("SEDIMENT");
         sp.setTitle("SEDIMENT"); // better to give the class this method
         sp.repaint();
         sp.revalidate();
    }
}

public class SedimentPanel {
    private TitledBorder titledBorder = ....;

    public void setTitle(String title) {
        titledBorder.setText(title);
    }
}   

然后,当您创建此侦听器时,将适当的引用传递给实际的可视化 JPanel。

你犯这个错误表明,阅读或重新阅读你的文章中关于对象/参考是什么以及它代表什么的一个体面的章节不会对你造成伤害,因为这是一个基础你犯的错误。

一个工作示例:

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

public class TitleExample {

    private static void createAndShowGui() {
        SedimentPanel sedimentPanel = new SedimentPanel();
        PanelTitle panelTitle = new PanelTitle(sedimentPanel); // pass in the reference
        JMenuItem menuItem = new JMenuItem("SEDIMENT");
        menuItem.addActionListener(panelTitle);
        JMenu jMenu = new JMenu("Menu");
        jMenu.add(menuItem);
        JMenuBar menuBar = new JMenuBar();
        menuBar.add(jMenu);

        JFrame frame = new JFrame("TitleExample");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(sedimentPanel);
        frame.setJMenuBar(menuBar);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

class SedimentPanel extends JPanel {
    private TitledBorder titledBorder = BorderFactory.createTitledBorder(null, "border title", TitledBorder.CENTER,
            TitledBorder.DEFAULT_POSITION);

    public SedimentPanel() {
        super();
        setBorder(titledBorder);
        setPreferredSize(new Dimension(400, 300));
    }

    public void setTitle(String title) {
        titledBorder.setTitle(title);
        repaint();
    }

}

class PanelTitle implements ActionListener{
    String title;
    private SedimentPanel sp;

    public PanelTitle(SedimentPanel sp){  // pass in reference
        this.sp = sp;
    }

    @Override
    public void actionPerformed(ActionEvent ae){
         sp.setTitle("SEDIMENT"); // better to give the class this method
    }
}