我的问题有点复杂了,我试图在点击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);
}
答案 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
}
}