Java 如何在Swing中绘制垂直线
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21347758/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to draw vertical line in Swing
提问by user3227258
I am able to draw a horizontal line but unable to draw a vertical line. Please help me.
我能画一条水平线,但不能画一条垂直线。请帮我。
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
class Success extends JFrame{
public Success(){
JPanel panel=new JPanel();
getContentPane().add(panel);
setSize(450,450);
JButton button =new JButton("press");
panel.add(button);
}
public void paint(Graphics g) {
super.paint(g); // fixes the immediate problem.
Graphics2D g2 = (Graphics2D) g;
Line2D lin = new Line2D.Float(20, 40, 850, 40);
g2.draw(lin);
}
public static void main(String []args){
Success s=new Success();
s.setVisible(true);
}
}
Thanks in advance.
提前致谢。
采纳答案by michaelsnowden
I noticed a couple things, some of them were already pointed out:
我注意到一些事情,其中一些已经被指出:
- To answer your question directly, this is what the (x, y) coordinates look like for Swing components
keep x coordinates the same for a vertical line. If you don't know where the x coordinates are in your line constructor when you create it, look at the documentation for the constructor. If you're using Eclipse, this means you should just hover your mouse over the code that contains the constructor.
- Your line goes outside the range of your JFrame; instead, if you want it to go from end to end, use the
getWidth()
andgetHeight()
methods. - You shouldn't be creating a new line every time you repaint your components. Instead, you should create the line somewhere in you
Success
class, implementActionListener
so you can update your code every frame, and in that update, resize your line, then leave just the repainting topaintComponent
. - You shouldn't override
JFrame
in this case, and you usually shouldn't have to. - You should override the
paintComponent
method, not thepaint
method. - I don't think you're double-buffering correctly, but I can't help you there.
- Overriding the
getPreferredSize
method of JPanel is handy if you want to control its size, but it's not even necessary in this case, because adding it to the JFrame will automatically size it for you.
- 要直接回答您的问题,这就是 Swing 组件的 (x, y) 坐标的样子,
使垂直线的 x 坐标保持相同。如果您在创建行构造函数时不知道 x 坐标在何处,请查看构造函数的文档。如果您使用的是 Eclipse,这意味着您应该将鼠标悬停在包含构造函数的代码上。
- 您的线路超出了 JFrame 的范围;相反,如果您希望它从头到尾运行,请使用
getWidth()
和getHeight()
方法。 - 您不应该每次重新绘制组件时都创建一个新行。相反,您应该在
Success
类中的某处创建该行,实施ActionListener
以便您可以在每一帧更新您的代码,并在该更新中调整您的行的大小,然后只将重绘保留为paintComponent
. JFrame
在这种情况下,您不应覆盖,而且通常不必这样做。- 您应该覆盖
paintComponent
方法,而不是paint
方法。 - 我认为您没有正确进行双缓冲,但我无法帮助您。
getPreferredSize
如果你想控制它的大小,覆盖JPanel的方法很方便,但在这种情况下甚至没有必要,因为将它添加到 JFrame 会自动为你调整它的大小。
There's a lot of stuff that goes on in Swing behind the scenes, and it can get confusing because normally you have to say stuff explicitly, but keep playing with this example, and you should be safe for a while.
在 Swing 的幕后有很多事情发生,它可能会让人感到困惑,因为通常您必须明确地说出来,但继续玩这个例子,你应该安全一段时间。
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.*;
class Success extends JPanel implements ActionListener{
private final Timer timer = new Timer(20, this); // Create a timer that will go off every 20 ms
Line2D horizontalLine; // Declare your variables here, but don't initialize them
Line2D verticalLine; // That way, they can be accessed later in actionPerformed and repaint
// You might want to try frame.setResizable(false) if you want your frame
// and your panel to stay the same size.
private final Dimension prefPanelSize = new Dimension(450, 450);
public Success(){
super(); // Call the constructor of JPanel, the class this subclasses.
JButton button =new JButton("press");
this.add(button);
this.setSize(prefPanelSize);
horizontalLine = new Line2D.Float(0, 40, prefPanelSize.width, 40);
verticalLine = new Line2D.Float(prefPanelSize.width / 2, 0,
prefPanelSize.width / 2, prefPanelSize.height);
timer.start(); // Start the timer
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g); // fixes the immediate problem.
Graphics2D g2 = (Graphics2D) g;
g2.draw(horizontalLine);
g2.draw(verticalLine);
}
@Override
public Dimension getPreferredSize()
{
return prefPanelSize;
}
public static void main(String []args){
Success s = new Success();
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setSize(new Dimension(450, 450));
frame.add(s);
}
// This method is called ever 20 ms because of the timer.
@Override
public void actionPerformed(ActionEvent e) {
int currWidth = getWidth();
int currHeight = getHeight();
horizontalLine.setLine(0, 40, currWidth, 40);
verticalLine.setLine(currWidth / 2, 0, currWidth / 2, currHeight);
}
}
回答by Karthik Kalyanasundaram
Keep the x co-ordinates the same and change value of y co-ordinates as shown below
保持 x 坐标相同并更改 y 坐标的值,如下所示
Line2D lin = new Line2D.Float(20, 40, 20, 150);
Line2D lin = new Line2D.Float(20, 40, 20, 150);
First two values are the (x1,y1) value of the starting point of the line and last two values (x2,y2) end point of the line. Now I hope you understand why your code produced a horizontal line and what needs to be done to draw vertical line.
前两个值是线起点的 (x1,y1) 值和线终点的最后两个值 (x2,y2)。现在我希望你明白为什么你的代码会产生一条水平线,以及绘制垂直线需要做什么。