我正在尝试使用JComponent类的PropertyChangeSupport。 但是当我执行以下代码时,首先单击菜单按钮会给运行时强制执行Exception,但它总是运行良好。
FrameListener.java
import javax.swing.*;
import java.beans.*;
import java.awt.*;
import java.awt.event.*;
public class FrameListener extends JFrame implements ActionListener, PropertyChangeListener
{
JLabel lblMessage;
JMenuItem changeFont;
FontSource fe = new FontSource(this,"Font Editor");
public FrameListener(){
super("Hello World");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) ;
increaseReadability() ;
changeFont.addActionListener(this);
fe.addPropertyChangeListener(this);
setSize(400,200);
setVisible(true);
}
private void increaseReadability(){
JPanel panel = new JPanel();
Font f = new Font("Times New Roman",Font.BOLD,24);
lblMessage = new JLabel("HELLO WORLD",SwingConstants.CENTER);
lblMessage.setFont(f);
panel.add(lblMessage);
JMenuBar actionBar = new JMenuBar();
JMenu edit = new JMenu("Edit");
changeFont = new JMenuItem("Font");
actionBar.add(edit);
edit.add(changeFont);
add(actionBar,BorderLayout.NORTH);
add(panel,BorderLayout.CENTER);
}
public void propertyChange(PropertyChangeEvent pcevent){
Object obj = pcevent.getNewValue() ;
System.out.println(obj.getClass()) ;
//Statement occuring problem 1st time
Font newFt = (Font)obj;
lblMessage.setFont(newFt);
}
public void actionPerformed(ActionEvent evt){
fe.setVisible(true);
}
public static void main(String argv[]) {
new FrameListener();
}
}
FontSource.java
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.beans.*;
public class FontSource extends JDialog implements ActionListener {
private Font newFont = new Font("Times New Roman",Font.BOLD,12);
JComboBox cbfType,cbfStyle,cbfSize;
JButton btnOk,btnCancel;
//protected PropertyChangeSupport changes = new PropertyChangeSupport(this);
public Font getNewFont(){
return newFont;
}
public void setNewFont(Font f){
Font old = newFont;
try{
//this statement calls the propertyChange() of FrameListener
//if u are removing comments, replace the following statement with
// changes.firePropertyChange("Font Changed",old,f);
firePropertyChange("Font Changed",old,f);
newFont = f;
}
catch(Exception e){
System.out.println(e);
}
}
public FontSource(Frame fr,String title){
super(fr,title);
// getting font family from the graphics environment.
GraphicsEnvironment gf = GraphicsEnvironment.getLocalGraphicsEnvironment();
String myfont[] = gf.getAvailableFontFamilyNames();
cbfType = new JComboBox(myfont);
add(cbfType);
String fontStyle[] = {"PLAIN","ITALIC","BOLD",};
cbfStyle = new JComboBox(fontStyle);
add(cbfStyle);
String fontSize[] = {"10","12","14","16","18","20","24","26","28","36","48","72"};
cbfSize = new JComboBox(fontSize);
add(cbfSize);
btnOk =new JButton("OK");
btnCancel =new JButton("Cancel");
add(btnOk);
add(btnCancel);
// adding action listener
btnOk.addActionListener(this);
btnCancel.addActionListener(this);
// setting layout and size for the dialog
setLayout(new FlowLayout());
setSize(170,170);
}
public void actionPerformed(ActionEvent ae){
if(ae.getSource()==btnOk){
String type = (String) cbfType.getSelectedItem();
String style = (String)cbfStyle.getSelectedItem();
int s = 0;
int size = Integer.parseInt((String)cbfSize.getSelectedItem());
if(style=="PLAIN")
s= Font.PLAIN;
else {
if(style =="BOLD")
s= Font.BOLD;
else
s= Font.ITALIC;
}
Font f = new Font(type,s,size);
setNewFont(f);
}
else{
this.setVisible(false);
}
}
/*
public void addPropertyChangeListener(PropertyChangeListener l){
System.out.println("attachement done...");
changes.addPropertyChangeListener(l);
}
public void removePropertyChangeListener(PropertyChangeListener l){
changes.removePropertyChangeListener(l);
}
*/
}
但如果我使用自己的PropertyChangeSupport(删除FontSource.java中的注释),那么它的工作正常。 我尽我所能,但没有得到这个。 Thnx提前: - )
答案 0 :(得分:3)
如果您实施PropertyListener
,您将收到您注册的组件的所有属性更改。可以有许多类型,其值将由属性更改的类型确定。
Component
setFont
方法的实施将触发名称为"font"
的属性更改。如果您测试该名称,您应该没问题:
public void propertyChange(PropertyChangeEvent pcevent){
Object obj = pcevent.getNewValue() ;
System.out.println(obj.getClass()) ;
//Problem should not occur with this call.
if (pcevent.getPropertyName().equals("font")){
Font newFt = (Font)obj;
lblMessage.setFont(newFt);
}
}
答案 1 :(得分:1)
我的猜测......
属性更改侦听无法通过属性名称进行区分。由于您正在收听FontSource的所有属性,因此您无疑会看到不是Font的内容。
在propertyChange()中,您可以在事件中打印属性名称,以确保问题出现。
解决方案是仅注册您感兴趣的属性,或者检查propertyChange()方法中的属性名称。
答案 2 :(得分:0)
最后我明白了。
当你编译并执行以下文件时,会显示答案。
<强> FontSource.java 强>
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.beans.*;
public class FontSource extends JDialog{
public FontSource(Frame fr,String title){
super(fr,title);
setSize(600, 400) ;
JTextArea area = new JTextArea() ;
area.setEditable(false) ;
add(new JScrollPane(area)) ;
String str = "If u look at the command prompt, then it is very clear," + "\n" +
"that, only on your first click on JMenuItem (font)," + "\n" +
"u get an output on cmd, for next future clicks on JMenuItem (font), u get no output on cmd." + "\n\n" +
"Reason : On first click, ActionListener attached to JMenuItem (font) invokes," + "\n" +
"fe.setVisible(true), which internally calls setBackground method of Component class only once." + "\n" +
"Now, setBackground method calls firePropertyChange(\"background\", oldValue, newValue)," + "\n" +
"which in turn also gets executed once." + "\n\n" +
"Now, solution to this is clearly mentioned in the reply" + "\n" +
"provided by akf for my question asked on stackoverflow. cheers :-)" ;
area.setText(str) ;
}
}
<强> FrameListener.java 强>
import javax.swing.*;
import java.beans.*;
import java.awt.*;
import java.awt.event.*;
public class FrameListener extends JFrame implements ActionListener, PropertyChangeListener
{
JLabel lblMessage;
JMenuItem changeFont;
FontSource fe = new FontSource(this,"Font Editor");
public FrameListener(){
super("Hello World");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) ;
increaseReadability() ;
changeFont.addActionListener(this);
fe.addPropertyChangeListener(this);
setSize(400,200);
setVisible(true);
}
private void increaseReadability(){
JMenuBar actionBar = new JMenuBar();
JMenu edit = new JMenu("Edit");
changeFont = new JMenuItem("Font");
actionBar.add(edit);
edit.add(changeFont);
add(actionBar,BorderLayout.NORTH);
}
public void propertyChange(PropertyChangeEvent pcevent){
Object obj = pcevent.getNewValue() ;
System.out.println(obj.getClass() + ", " + pcevent.getPropertyName()) ;
}
public void actionPerformed(ActionEvent evt){
fe.setVisible(true);
}
public static void main(String argv[]) {
new FrameListener();
}
}