【问题标题】:How do I change the size of a rectangle while painting a histogram?如何在绘制直方图时更改矩形的大小?
【发布时间】:2014-01-04 11:14:28
【问题描述】:

实际上我是 java gui 的新手,在这里,每当我们在文本字段中输入内容并按下按钮时,我都想更改矩形高度,但我不知道该怎么做,实际上我签入了大量站点但我找不到简单的方法。实际上我找不到如何更改 MyPanel 类中的paintComponent 内的矩形大小。

(高度变化的逻辑是字符串中有多少元音大小写,辅音等)

import java.awt.*;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Hist{
    int h1=0,h2=0,h3=0,h4=0,h5=0;
    JFrame f=new JFrame();
    JButton b=new JButton("click");
    JTextField text=new JTextField(30);


public static void main(String args[]){
    Hist h=new Hist();

}

Hist(){

    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setLayout(new FlowLayout());
    f.add(new MyPanel(h1,h2,h3,h4,h5));
    f.setSize(400,300);
    f.setVisible(true);

    f.add(b);
    f.add(text);

    thehandler handler=new thehandler();
    b.addActionListener(handler);

}
class thehandler implements ActionListener{
    public void actionPerformed(ActionEvent event){
        if(event.getSource()==b){
            h1=0;h2=0;h3=0;h4=0;h5=0;
            String s;
            s=text.getText();
            char[] ar=s.toCharArray();
            for(int i=0;i<s.length();i++){
                if(ar[i]=='a'||ar[i]=='e'||ar[i]=='i'||ar[i]=='o'||ar[i]=='u'){
                    h1=h1+10;
                }
                else if(ar[i]=='A'||ar[i]=='E'||ar[i]=='I'||ar[i]=='O'||ar[i]=='U'){
                    h2=h2+10;
                }
                else{
                    h5=h5+10;
                }
            }

        }
    }

 }
}


class MyPanel extends JPanel{
    int x1,x2,x3,x4,x5;
    public MyPanel(int a,int b,int c,int d,int e){
        setBorder(BorderFactory.createLineBorder(Color.BLACK));
        x1=a;x2=b;x3=c;x4=d;x5=e;
    }
    public Dimension getPreferredSize(){
        return new Dimension(350,200);
    }
    public void paintComponent(Graphics g){
        super.paintComponents(g);
        g.setColor(Color.red);
        g.fillRect(25, 25, 30,x1);

        g.setColor(Color.red);
        g.fillRect(75, 25, 30, x2);

        g.setColor(Color.red);
        g.fillRect(125, 25, 30,x3);

        g.setColor(Color.red);
        g.fillRect(175, 25, 30, x4);

        g.setColor(Color.red);
        g.fillRect(225, 25, 30, x5);

    }
}

【问题讨论】:

  • 开启ActionEvent 获取/设置新值并调用repaint()
  • h1h2.. 是否与x1x2.. 属性相关联?我发现你的变量名令人困惑,因为它们的使用方式 x 属性被用作 height 前缀 h!

标签: java swing user-interface graphics paint


【解决方案1】:

“实际上我找不到如何更改paintComponent 内部的矩形大小”

看起来你这样做的方式只会改变高度而不是y 位置。如果是倒置的直方图就好了。

你需要做的是有一个 y 的起点,比如高度为 450 的屏幕为 400,因此地平线接近底部

int y = 400;

所以当你画出来的时候

g.fillRect(25, y - height, 30, height)

现在高度将是y起点,400。当你想增加它时,你实际上需要减少400。

所以如果你希望高度为150,那么你需要-150

g.fillRect(25, y - 150, 30, height);

这会给效果一个从地平线上升的条

对于每个g.fillRect,您应该计算一个新的高度,这样您就可以拥有一个height 变量。和一个基于元音数量的final INCREMENT 变量。所以像这样的

final int INCREMENT = 25;
int height;

....

height = numberOfAs * INCREMENT;
g.fillRect(25, y - height, 30, height);
height = numberOfEs * INCREMENT;
g.fillRect(75, y - height, 30, height);
height = numberOfOs * INCREMENT;
g.fillRect(125, y - height, 30, height);
height = numberOfIs * INCREMENT;
g.fillRect(175, y - height, 30, height);
height = numberOfUs * INCREMENT;
g.fillRect(225, y - height, 30, height);

运行这个例子看看我在说什么

import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Histogram extends JPanel {

    private static final int DIM_WIDTH = 300;
    private static final int DIM_HEIGHT = 450;

    int height;
    private static final int INCREMENT = 50;
    int numberOfAs = 4;
    int numberOfEs = 2;
    int numberOfIs = 1;
    int numberOfOs = 5;
    int numberOfUs = 6;
    int y = 400;

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        height = numberOfAs * INCREMENT;
        g.fillRect(25, y - height, 30, height);
        height = numberOfEs * INCREMENT;
        g.fillRect(75, y - height, 30, height);
        height = numberOfOs * INCREMENT;
        g.fillRect(125, y - height, 30, height);
        height = numberOfIs * INCREMENT;
        g.fillRect(175, y - height, 30, height);
        height = numberOfUs * INCREMENT;
        g.fillRect(225, y - height, 30, height);
    }

    public static void createAndShowGui() {
        JFrame frame = new JFrame();
        frame.add(new Histogram());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationByPlatform(true);
        frame.pack();
        frame.setVisible(true);

    }

    public Dimension getPreferredSize() {
        return new Dimension(DIM_WIDTH, DIM_HEIGHT);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

从左到右,INCREMENT 为每个字母 50 像素

As = 4;
Es = 2;
Os = 5;
Is = 1;
Us = 6;

另外在您希望能够通过文本字段条目控制重绘的程序中,您可以在 MyPanel 类中设置 setters,该类将设置numberOfXs 变量。在通过任何方法获取它们后,只需调用 setNumberOfAs(int numberOfAs) 和其余的设置器,然后调用 repaint。因此,每次从 textField 中获取输入,并且您更新了 MyPanel 中的变量时,绘制的直方图都应该更新。


更新

另一种方法是使ActionListener 成为HistMyPanel 内部类。这样他们就可以共享Hist 的全局变量。使NumberOfXs 成为Hist 类的变量成员,以便所有内部类都可以共享。在actionPerformedActionListener 类中,相应地更改变量并将repaint 更改为MyPanel。如果你这样做了,你就不需要向MyPanel的构造函数传递参数了


更新 2

我不想为你完成你的完整作业,所以我给你一个基本的大纲。

  • 将两个类都设为Hist 的内部类
  • 拥有HistnumberOfXs 变量类成员,而不是MyPanel
  • Hist 中创建MyPanel 的实例作为类成员,以便ActionListener 可以访问它
  • actionPerformed 中获取numberOfXs 的值,然后调用repaint

类似的东西

public class Hist {
    MyPanel myPanel = new MyPanel();
    int numberOfAs;
    int numberOfEs;
    int numberOfIs;
    int numberOfOs;
    int numberOfUs;

    private class MyPanel extends JPanel {
        // do your painting
    }

    private class MyListener implements ActionListener {
        public void actionPerformed(ActionEvent e){
            // get the values for numberOfXs however you do it. Make sure to numberOfXs = someValue
            myPanel.repaint();
        }
    }
}

【讨论】:

  • 谢谢,这正是我想要的,但现在我想添加一个带有文本字段的按钮来接受输入并更改 As 、Es 的值并分别更改直方图。
  • 另外,请参阅我的 UPDATE
  • 对不起兄弟,再问你一次,但这是我的第一个重绘程序,我无法做到,请你修改你的代码并告诉我重绘。
  • 哇!我简单地查看了代码,意识到它有很多问题,我没有时间去研究它。你的努力太棒了。和一个优秀的截图只是为了让它变得更好。太棒了.. :)
【解决方案2】:

在您的 MyPanel 中定义一个方法来传递值并将它们设置到 x1 - x5 字段。

例如

public void setValues(int a,int b,int c,int d,int e){
    x1=a;x2=b;x3=c;x4=d;x5=e;
}

当某些事情发生变化时,只需使用适当的计算值调用 setValues()。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-28
    • 2022-10-16
    相关资源
    最近更新 更多