英文:
GUI application that the shape changes on a radio button click
问题
我的应用程序的目标是在单选按钮点击时更改背景和前景,并根据单选按钮更改项目的形状。我正在尝试使应用程序根据所选单选按钮实时更改形状。我已经让背景和前景正常工作了,但形状却没有。我看到过另一篇类似的帖子,但它有一个提交按钮,并且没有使用 JSlider。
以下是我一直在尝试但似乎无法正确执行程序的部分。我已经成功改变了形状,但滑块却失效了。我是不是方法错了?
public class OvalPanel extends JPanel {
private int diameter = 10; // 默认直径
// 绘制指定直径的椭圆形
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (rectFillRadioButton.isSelected()) {
g.fillRect(10, 10, 10, 10);
}
if (ovalFillRadioButton.isSelected()) {
g.fillOval(10, 10, 10, 10);
}
}
// 验证并设置直径,然后重绘
public void setDiameter(int newDiameter) {
// 如果直径无效,则默认为10
diameter = (newDiameter >= 0 ? newDiameter : 10);
repaint(); // 重绘面板
}
// 由布局管理器用于确定首选大小
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
// 由布局管理器用于确定最小大小
public Dimension getMinimumSize() {
return getPreferredSize();
}
}
这是我最初设置了 paintComponent 的类。我还有以下部分:
private class TopRadioButtonHandler extends JFrame implements ItemListener {
private Graphics panel;
public TopRadioButtonHandler(Graphics p) {
panel = p;
}
@Override
public void itemStateChanged(ItemEvent event) {
if (rectFillRadioButton.isSelected()) {
panel = myPanel.getGraphics();
panel.fillRect(10, 10, 10, 10);
repaint();
}
if (ovalFillRadioButton.isSelected()) {
panel = myPanel.getGraphics();
panel.fillOval(10, 10, 10, 10);
repaint();
}
}
}
我认为我不需要 repaint,但当我使用这个方法时,我的 JSlider 停止工作了。
英文:
What my application is meant to do is change the background and foreground on a click of a radio button and change the shape of the item based on a radio button.I am trying to get my application to actively change shape based on the radio button that is selected.I have the background and foreground working just not the shape. I have seen another post kinda like this but it has a submit button and does not use the JSlider
Below is what I have been messing with and cannot seem to get the program to execute correctly. I have gotten the shape to change but then the slider breaks. Am i approaching this the wrong way?
public class OvalPanel extends JPanel
{
private int diameter = 10; // default diameter
// draw an oval of the specified diameter
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if(rectFillRadioButton.isSelected()){
g.fillRect(10,10,10,10);
//repaint();
}
if(ovalFillRadioButton.isSelected()){
g.fillOval(10,10,10,10);
//repaint();
}
}
// validate and set diameter, then repaint
public void setDiameter(int newDiameter)
{
// if diameter invalid, default to 10
diameter = (newDiameter >= 0 ? newDiameter : 10);
repaint(); // repaint panel
}
// used by layout manager to determine preferred size
public Dimension getPreferredSize()
{
return new Dimension(200, 200);
}
// used by layout manager to determine minimum size
public Dimension getMinimumSize()
{
return getPreferredSize();
}
}
this is the class that i initially have that sets the paintComponent. I also have
private class TopRadioButtonHandler extends JFrame implements ItemListener {
private Graphics panel;
public TopRadioButtonHandler(Graphics p) {
panel = p;
}
@Override
public void itemStateChanged(ItemEvent event) {
if(rectFillRadioButton.isSelected()){
panel = myPanel.getGraphics();
panel.fillRect(10,10,10,10);
repaint();
}
if(ovalFillRadioButton.isSelected()){
panel = myPanel.getGraphics();
panel.fillOval(10,10,10,10);
repaint();
}
}
}
i dont think i need the repaint but when i use this method my JSlider stops working.
答案1
得分: 0
> 我的方法错了吗?
是的,paintComponent() 方法不应该引用另一个 Swing 组件。
当您进行自定义绘制时,paintComponent() 应该只绘制组件的当前状态。
例如,当您使用 Jlabel 时,有像 setText() 和 setIcon() 这样的方法,用于设置要绘制的文本和图标。
您已经有一个名为 setDiameter() 的方法,这是一个不错的开端。然而,您的绘制代码只是硬编码了椭圆/矩形的大小。绘图方法应该引用您的直径变量。
现在,您需要另一个属性来指示是绘制椭圆还是矩形。因此,也许您需要一个名为 setPaintOval(boolean paintOval)
的属性。
然后您的绘图代码可能是:
if (paintOval)
g.fillOval(10, 10, diameter, diameter);
else
g.fillRect(10, 10, diameter, diameter);
当然,这种方法的问题是您只能绘制两个对象。
另外,在绘图方法中永远不应该调用 repaint()。repaint() 应该仅在您更改组件状态的 setter 方法中调用。
> 但是滑块就会出问题
您发布的代码与滑块无关。
我猜您希望滑块能够改变椭圆的直径?您需要向滑块添加一个 ChangeListener
,然后使用滑块的值调用您的 setDiameter() 方法。
阅读 Swing 教程中关于如何使用滑块的章节,其中有一个工作示例。
英文:
> Am i approaching this the wrong way?
Yes, the paintComponent() method should not be referencing another Swing component.
When you do custom painting, the paintComponent() should only paint the current state of your component.
For example when you use a Jlabel you have methods like setText() and setIcon() to set the text and icon you want to paint.
You already have a method, setDiameter() which is a good start. However, your painting code just hard codes the size of the oval/rectangle. The painting methods should reference you diameter variable.
Now, you need another property to idicate whether to paint an oval or a rectangle. So maybe you need a property like setPaintOval(boolean paintOval)
.
Then your painting code could be:
If (paintOval)
g.fillOval(10, 10, diameter, diameter);
else
g.fillRect(10, 10, diameter, diameter);
Of course the problem with this approach is that you can only paint two objects.
Also, you should never invoke repaint() in a painting method. The repaint() should only be invoked from your setter methods when you change the state of the component.
> but then the slider breaks
The code you posted has nothing to do with a slider.
I'm guessing you want the slider to change the diameter of the oval? Well you need to add a ChangeListener
to the slider and then invoke your setDiameter() method with the slider value.
Read the section from the Swing tutorial on How to Use Sliders for a working example.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论