【问题标题】:Changing the value of a outer class member via a inner class通过内部类更改外部类成员的值
【发布时间】:2013-07-07 16:54:18
【问题描述】:

我正在尝试通过内部类事件处理方法来操作外部类成员。

一个类MyColorChooser 有一个私有成员sliderColorsliderColor的默认值在构造函数中设置为黑色。

内部类用于通过来自JSliders 的用户输入来处理新颜色的构造。然后我通过外部类中的 setter 方法将 sliderColor 的值设置为这个新颜色。

问题是外部类的一个实例使用它自己的getColor 方法,该方法总是返回构造函数设置的值(黑色),而不是分配给它的新值。如何让内部类方法能够直接改变外部成员变量中的值?

更新

是的,它似乎应该可以工作,但让我很困惑为什么它不......我已经发布了一些我相信的相关位 f 代码:

如果代码不合适,请提前道歉,因为不确定要插入多少......

调试: 我已经调试并注意到颜色是它应该在内部类和 setColour 外部类方法中的颜色......所以我怀疑它已被更改回默认构造函数值......只是不确定在哪里或由什么...... .我只是继续调试

类 MyColorChooser 允许通过内部类事件处理程序处理的 JSlider 的输入创建颜色对象:

* Part 4 
* JPanel subclass that alloews the user define the color attributes for shapes 
* utlising 3 JSliders 
*/ 
package Assignment2; 

import java.awt.Color; 
import java.awt.GridLayout; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JSlider; 
import javax.swing.JTextField; 
import javax.swing.SwingConstants; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 

/** 
* 
* @author Ciaran Mooney dancingbush@gmail.com 
*/ 
public class MyColorChooser4 extends JPanel { 

//declare instance varibles 
//JSlider colors 
private JSlider blueSlider; 
private JSlider greenSlider; 
private JSlider redSlider; 
//display color chossen by user varibles 
private JTextField redChoice; 
private JTextField greenChoice; 
private JTextField blueChoice; 
private DrawPanel shapeColor = new DrawPanel(); //set color of drawpanel onbject 
//prompts for user input 
private JLabel redInput; 
private JLabel blueInput; 
private JLabel greenInput; 
//color object created 
private Color colorChoice ; ; 
private JTextField theColor; 

//no arg GUI construtor gets user input and constructs color 
public MyColorChooser4() { 

//default layout of panel is set to GridLayout 4 cols 4 rows 
this.setLayout(new GridLayout(4, 4)); 


greenInput = new JLabel("Green: "); 
greenSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 255, 1); 
greenChoice = new JTextField("0", 4);//default text 
greenChoice.setEditable(false); 

add(greenInput); 
add(greenSlider); 
add(greenChoice); 

redInput = new JLabel("Red: "); 
redSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 255, 1); 
redChoice = new JTextField("0", 4);//default text 
redChoice.setEditable(false); 

add(redInput); 
add(redSlider); 
add(redChoice); 

blueInput = new JLabel("Blue: "); 
blueSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 255, 1); 
blueChoice = new JTextField("0", 4);//default text 
blueChoice.setEditable(false); 

add(blueInput); 
add(blueSlider); 
add(blueChoice); 

//set default color black and declare inner class event handlers 
//sliders utlise ChengeListeners 

greenSlider.addChangeListener(new SlideHandler()); 
redSlider.addChangeListener(new SlideHandler()); 
blueSlider.addChangeListener(new SlideHandler()); 

colorChoice = Color.RED; 

//label to diplay color chosen, and blnk JLabel to move color to center 
theColor = new JTextField(4); 
JLabel preview = new JLabel(" "); 
add(preview); 
add(theColor); 
theColor.setBackground(colorChoice); 


}//end GUI constructor 

//set color 
public void setSlideColor(Color colorSlide) { 
colorChoice = colorSlide; 

}//end set colorChoice 

//get methods for fields 
public Color getColor() { 

return colorChoice; 

}//end getColor 

//return slider for red value 
public JSlider getRedSlider() { 
return redSlider; 
}//edn get red slider 

//retirn slider for green value 
public JSlider getGreenSlider() { 
return greenSlider; 
}//edn getGreenSlider 

//return slider for blue value 
public JSlider getBlueSlider() { 
return blueSlider; 
}//end getGreenSlider 

//private inner class for event handliing on sliders & implement abstract class 
private class SlideHandler implements ChangeListener { 

private Color colorSlide; 

@Override 
public void stateChanged(ChangeEvent e) { 

//return integers from sliders 
int blue = blueSlider.getValue(); 
int green = greenSlider.getValue(); 
int red = redSlider.getValue(); 

//now construct a new color based on these values 

colorSlide = new Color(red, green, blue); 
setSlideColor(colorSlide); 


//display integer value of color chosen in relative textfield 
//use String method valueOf to return string rep of integer 
//display chossen color in text area 
redChoice.setText(String.valueOf(red)); 
redChoice.setBackground(new Color(red, 0, 0)); 
greenChoice.setText(String.valueOf(green)); 
greenChoice.setBackground(new Color(0, green, 0)); 
blueChoice.setText(String.valueOf(blue)); 
blueChoice.setBackground(new Color(0, 0, blue)); 

//set chosen color preview 
theColor.setBackground(colorChoice); 
theColor.setText("Preview"); 


}//end stateChanged method 
}//end inner class SlideHandler 
}//end class MyColorChooser4

然后是类 ShapePanel,它是一个菜单,用户可以在该菜单中选择要绘制的形状的各种属性,包括颜色。通过颜色对象数组的 JComobobox 选择来确定颜色。 MyColorChooser4 中的颜色是通过调用其 getColor 方法的 teh 类的实例获取的:

上述的声明和实现

public DrawPanel draw = new DrawPanel(); 
private MyColorChooser4 sliderColor = new MyColorChooser4(); 

//array holding color objects 
private Color colors[] = {Color.BLACK, Color.BLUE, Color.CYAN, 

Color.DARK_GRAY, Color.GRAY, Color.GREEN, Color.LIGHT_GRAY, 
Color.MAGENTA, Color.ORANGE, Color.PINK, Color.RED, Color.WHITE, 
Color.YELLOW, sliderColor.getColor()}; 

//array carrying color strings 
private String colorNames[] = {"Black", "Blue", "Cyan", 
"Dark Gray", "Gray", "Green", "Light Gray", "Magenta", 
"Orange", "Pink", "Red", "White", "Yellow", "Slider Color"};

ShapePanel 类的事件处理方法,允许选择颜色......

color = new JComboBox(colorNames); 
color.setMaximumRowCount(6); 
color.addItemListener(new ItemListener() { 

@Override 
public void itemStateChanged(ItemEvent e) { 

if (e.getStateChange() == ItemEvent.SELECTED) { 
draw.setCurrentColor((colors[color.getSelectedIndex()]));; 

} //end if 
}//end itemStateChnaged 
});//end annmonouys class and action event method 

componments.add(color); 

DrawPanel 类的实例 draw 通过下面的 set 方法设置形状应该被绘制的颜色.....

//set current color 
public void setCurrentColor(Color color) { 


//set currentColor from JCombox input handler 
currentColor = color; 


//generate a random startColor for Gradient color 
int red = (int) (Math.random() * 256); 
int green = (int) (Math.random() * 256); 
int blue = (int) (Math.random() * 256); 

//cyclic vs acylic fill 
colorFillStyle = new Random(); 
boolean gradientShift = colorFillStyle.nextBoolean(); 



 //create gradient object 
 Color startColor = new Color(red, green, blue); 
 gradientColor = new GradientPaint(10f, 10f, startColor, 350f, 350f, currentColor,         gradientShift); 


}//end set color method

然而,当绘制形状时,颜色始终为红色,反映了 MyColorChooser4 构造函数中的颜色初始化值....

希望这有点用......

【问题讨论】:

  • 不看代码怎么能找到问题?
  • 欢迎来到 Stack Overflow。请创建一个简单的程序来说明您要做什么。您可以在此处发布该代码,以便我们帮助您填写详细信息。

标签: java swing


【解决方案1】:

如果不查看您的代码,就无法确定问题所在,但有两种可能性:

1:你的外部类中的set方法不正确。似乎不太可能,但总是值得检查,因为它可能写成:

public void setColor(Color color)
{
    // Should be this.color =
    color = color;
}

2:您的内部类没有调用外部类的 set 方法,可能内部类已经声明了自己的 set 方法,该方法在您的调用中具有优先权。

3:内部类实际上从未被调用,可能是因为您的事件没有被触发。

最终,您的 setMethod 没有被调用,它没有做您认为它应该做的事情,或者在您调用 set 方法后其他事情正在重置值。据我所知,这些是您的值无法按预期设置的唯一可能性。

如果您发布代码,那么我们可以为您的问题提供更具体的答案。

【讨论】:

  • 我认为问题可能在于两个 sep 实例。我正在使用 MyColorChooser 的 diff 实例来渲染 JSlider JPanel,然后将其添加到内部框架中,我在 sep 类中创建了一个 sep 实例来调用 getColor 方法。如果是这样,是否可以在同一个包的多个类中使用同一个实例?是否将实例声明为静态?
  • @dancingbush 我不编写 Swing 组件,所以我不确定您是否可以使用相同的 JPanel 实例两次进行渲染,但是如果您只渲染一次并声明第二个实例仅用于访问这些值那么您当然可以共享它(这里只关心您的程序是否是多线程的并且您需要使访问线程安全)。使用静态是一种方法,但理想情况下,您可以将 ColorChooser 实例传递给每个需要它的对象,无论是在该对象的构造函数中还是通过 set 方法注入。
  • 谢谢。我使用 MyColorChooser 的单例类控制 obj 创建,以确保两个对象共享相同的颜色......现在我清楚地看到,当创建 MyColorChosser4 实例时,它包含此类的所有默认值,即颜色 = RED。但是当我查看类本身时,我看到颜色根据 JSlider 输入发生了变化……所以不知何故,类的一个实例没有类在其当前状态下的任何值……
  • @dancingbush 仅供参考,单例通常被认为是一种反模式(尽管它们可以说是为了方便起见)。如果您要使用一个,我建议您通过接口引用它,并尽可能将单例的实际实例注入使用它的类中,而不是让这些类静态引用它。这允许在单元测试时轻松地模拟和替换它。这是一般建议,可能不适用于您的具体情况和代码。
【解决方案2】:

@increment1 我避免了单例策略,并通过在一个类中创建所有实例 req 并通过将侦听器附加到事件处理程序来实现所需的更改。 .

我的问题是我期望我的 drawPanel 类的两个独立实例具有相同的行为,但没有经过深思熟虑和缺乏经验。

再次感谢 C

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-11
    • 2018-06-26
    • 2013-10-21
    • 1970-01-01
    • 2016-04-08
    • 1970-01-01
    相关资源
    最近更新 更多