Java Swing 中的画线
DrawLine in Java Swing
主要思想是 - 当滑块的值增长时,更多的线将组件分成相等的部分并且不与多边形的线交叉(就像它在图片的左上角)。我想对所有角都这样做,但现在我只对其中一个角做了。
有人能告诉我需要更改什么才能使线条达到宽度的 1/3 吗?
我的值适用于 1/2 但不适用于 1/3,n
是滑块的变量。
我的代码:
import java.awt.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Mariusz extends JFrame {
private int n = 5;
private Color kolor = Color.RED;
MyComponent komponent = null;
private class MyComponent extends JComponent
{
protected void paintComponent (Graphics grafika)
{
grafika.setColor(kolor);
grafika.drawLine(getWidth() * 1/3, 0, 0, getHeight() * 1/3);
grafika.drawLine(0, getHeight() * 1/3, getWidth() * 1/3, getHeight());
grafika.drawLine(getWidth() * 1/3, getHeight(),getWidth(), getHeight() * 1/3);
grafika.drawLine(getWidth(), getHeight() * 1/3, getWidth() * 1/3, 0);
for (int i = 0; i < n ; i++)
{
if (i <= n / 3)
{
grafika.drawLine(getWidth() * i /n, 0, getWidth() * i /n, (getHeight() - getHeight() * 2/3 ) - getHeight() * i / n); //lewy gorny
grafika.drawLine( getWidth() * i / n,(getHeight() - getHeight() * 2/3 ) + getHeight() * i / n + getHeight() *1/3, getWidth() * i / n, getHeight() );
}
if (i > n / 3)
{
grafika.drawLine(getWidth() * i / n , 0, getWidth() * i /n, getHeight() * 2 * i /n / 3 - getHeight() * 1 /3 );
}
}
}
}
public Mariusz(String string)
{
super(string);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Toolkit kit = Toolkit.getDefaultToolkit();
Dimension d = kit.getScreenSize();
setBounds( d.width / 4, d.height / 4, d.width / 2, d.height / 2);
add (komponent = new MyComponent());
JPanel panel = new JPanel(new BorderLayout());
add(panel,BorderLayout.SOUTH);
final JSlider slider = new JSlider(3,40,n);
slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
// TODO Auto-generated method stub
n = slider.getValue();
komponent.repaint();
}
});
panel.add(slider);
setVisible(true);
}
public static void main(String[] args)
{
// TODO Auto-generated method stub
EventQueue.invokeLater(new Runnable() {
public void run() {
new Mariusz("triangles");
}
});
}
}
您的方法是临时的,我无法相信它会在其他措施(4/5 等)中取得成功。
这是一种基于相似三角形的方法:
从右上角开始向后计算:
h1/h2=(2*w/3)/(2*w/3-(1/n)*(2*w/3))
因此
h2=h1/(.....)
其中 h1=h/3.
将其转换为代码
double f=2./3, f2=1-f;
g2.setColor(Color.blue);
for (int i=n-1; i>-1; i--)
{
grafika.drawLine(getWidth() * (n-i) / n, 0, getWidth() * (n-i)/n,
(int)((getHeight()/ 3)/(f/(f-1.*i/n))) );
}
对于左上角,我们以相同的方式工作,但使用因子 f2:
g2.setColor(Color.green);
for (int i=0; i<n; i++)
{
grafika.drawLine(getWidth() * i / n , 0, getWidth() * i /n, (int)((getHeight()/ 3)/(f2/(f2-1.*i/n))) );
}
左下同理:
g2.setColor(Color.magenta);
for (int i=0; i<n; i++)
{
grafika.drawLine(getWidth() * i / n , getHeight()-(int)((2*getHeight()/ 3)/(f2/(f2-1.*i/n))), getWidth() * i /n, getHeight() );
}
和右下方
g2.setColor(Color.black);
for (int i=n-1; i>-1; i--)
{
grafika.drawLine(getWidth() * (n-i) / n , getHeight()-(int)((2*getHeight()/ 3)/(f/(f-1.*i/n))), getWidth() * (n-i) /n, getHeight() );
}
例如,如果你想要一个 4/5 的尺寸,你必须将 f=4./5 和所有 2*getHeight()/3 更改为 4*getHeight()/5(getHeight()/3到 getHeight()/5 等)。
让我建议一个不同的方法。不要纠结于从边缘画线直到与多边形相交的数学问题,而是绘制规则的、完整的、垂直的线,然后将多边形覆盖在它们上面。
首先,要设置 3 件事:
protected void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
Graphics2D grafika = (Graphics2D) graphics;
- 始终调用
super
方法作为您在 paintComponent
中做的第一件事以避免伪影(除非您知道自己在做什么)。
- 将
Graphics
对象转换为更高级的 Graphics2D
对象总是安全的。
- 将宽度和高度保存到局部变量以减少内部调用的次数
paintComponent()
。
现在,使用这个非常简单的循环画线:
for (int i = 0; i < n; i++)
grafika.drawLine(w * i / n, 0, w * i / n, h);
这只是循环的减少。您可能需要根据您的要求修改它,但请注意 y
坐标拉伸整个组件高度。
然后根据 drawLine
方法中的点创建一个 Polygon
:
Polygon poly = new Polygon();
poly.addPoint(w * 1 / 3, 0);
poly.addPoint(0, h * 1 / 3);
poly.addPoint(w * 1 / 3, h);
poly.addPoint(w, h * 1 / 3);
最后,设置填充此形状的颜色,绘制它,设置形状轮廓的颜色并再次绘制:
grafika.setColor(getBackground());
grafika.fill(poly); // draws the inside
grafika.setColor(kolor);
grafika.draw(poly); // draws the outline
希望这不是作弊..
另外,这一行
add(komponent = new MyComponent());
在我看来看起来像是麻烦的根源。把它分成 2 个。
主要思想是 - 当滑块的值增长时,更多的线将组件分成相等的部分并且不与多边形的线交叉(就像它在图片的左上角)。我想对所有角都这样做,但现在我只对其中一个角做了。
有人能告诉我需要更改什么才能使线条达到宽度的 1/3 吗?
我的值适用于 1/2 但不适用于 1/3,n
是滑块的变量。
我的代码:
import java.awt.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Mariusz extends JFrame {
private int n = 5;
private Color kolor = Color.RED;
MyComponent komponent = null;
private class MyComponent extends JComponent
{
protected void paintComponent (Graphics grafika)
{
grafika.setColor(kolor);
grafika.drawLine(getWidth() * 1/3, 0, 0, getHeight() * 1/3);
grafika.drawLine(0, getHeight() * 1/3, getWidth() * 1/3, getHeight());
grafika.drawLine(getWidth() * 1/3, getHeight(),getWidth(), getHeight() * 1/3);
grafika.drawLine(getWidth(), getHeight() * 1/3, getWidth() * 1/3, 0);
for (int i = 0; i < n ; i++)
{
if (i <= n / 3)
{
grafika.drawLine(getWidth() * i /n, 0, getWidth() * i /n, (getHeight() - getHeight() * 2/3 ) - getHeight() * i / n); //lewy gorny
grafika.drawLine( getWidth() * i / n,(getHeight() - getHeight() * 2/3 ) + getHeight() * i / n + getHeight() *1/3, getWidth() * i / n, getHeight() );
}
if (i > n / 3)
{
grafika.drawLine(getWidth() * i / n , 0, getWidth() * i /n, getHeight() * 2 * i /n / 3 - getHeight() * 1 /3 );
}
}
}
}
public Mariusz(String string)
{
super(string);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Toolkit kit = Toolkit.getDefaultToolkit();
Dimension d = kit.getScreenSize();
setBounds( d.width / 4, d.height / 4, d.width / 2, d.height / 2);
add (komponent = new MyComponent());
JPanel panel = new JPanel(new BorderLayout());
add(panel,BorderLayout.SOUTH);
final JSlider slider = new JSlider(3,40,n);
slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
// TODO Auto-generated method stub
n = slider.getValue();
komponent.repaint();
}
});
panel.add(slider);
setVisible(true);
}
public static void main(String[] args)
{
// TODO Auto-generated method stub
EventQueue.invokeLater(new Runnable() {
public void run() {
new Mariusz("triangles");
}
});
}
}
您的方法是临时的,我无法相信它会在其他措施(4/5 等)中取得成功。
这是一种基于相似三角形的方法:
从右上角开始向后计算:
h1/h2=(2*w/3)/(2*w/3-(1/n)*(2*w/3))
因此
h2=h1/(.....)
其中 h1=h/3.
将其转换为代码
double f=2./3, f2=1-f;
g2.setColor(Color.blue);
for (int i=n-1; i>-1; i--)
{
grafika.drawLine(getWidth() * (n-i) / n, 0, getWidth() * (n-i)/n,
(int)((getHeight()/ 3)/(f/(f-1.*i/n))) );
}
对于左上角,我们以相同的方式工作,但使用因子 f2:
g2.setColor(Color.green);
for (int i=0; i<n; i++)
{
grafika.drawLine(getWidth() * i / n , 0, getWidth() * i /n, (int)((getHeight()/ 3)/(f2/(f2-1.*i/n))) );
}
左下同理:
g2.setColor(Color.magenta);
for (int i=0; i<n; i++)
{
grafika.drawLine(getWidth() * i / n , getHeight()-(int)((2*getHeight()/ 3)/(f2/(f2-1.*i/n))), getWidth() * i /n, getHeight() );
}
和右下方
g2.setColor(Color.black);
for (int i=n-1; i>-1; i--)
{
grafika.drawLine(getWidth() * (n-i) / n , getHeight()-(int)((2*getHeight()/ 3)/(f/(f-1.*i/n))), getWidth() * (n-i) /n, getHeight() );
}
例如,如果你想要一个 4/5 的尺寸,你必须将 f=4./5 和所有 2*getHeight()/3 更改为 4*getHeight()/5(getHeight()/3到 getHeight()/5 等)。
让我建议一个不同的方法。不要纠结于从边缘画线直到与多边形相交的数学问题,而是绘制规则的、完整的、垂直的线,然后将多边形覆盖在它们上面。
首先,要设置 3 件事:
protected void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
Graphics2D grafika = (Graphics2D) graphics;
- 始终调用
super
方法作为您在paintComponent
中做的第一件事以避免伪影(除非您知道自己在做什么)。 - 将
Graphics
对象转换为更高级的Graphics2D
对象总是安全的。 - 将宽度和高度保存到局部变量以减少内部调用的次数
paintComponent()
。
现在,使用这个非常简单的循环画线:
for (int i = 0; i < n; i++)
grafika.drawLine(w * i / n, 0, w * i / n, h);
这只是循环的减少。您可能需要根据您的要求修改它,但请注意 y
坐标拉伸整个组件高度。
然后根据 drawLine
方法中的点创建一个 Polygon
:
Polygon poly = new Polygon();
poly.addPoint(w * 1 / 3, 0);
poly.addPoint(0, h * 1 / 3);
poly.addPoint(w * 1 / 3, h);
poly.addPoint(w, h * 1 / 3);
最后,设置填充此形状的颜色,绘制它,设置形状轮廓的颜色并再次绘制:
grafika.setColor(getBackground());
grafika.fill(poly); // draws the inside
grafika.setColor(kolor);
grafika.draw(poly); // draws the outline
希望这不是作弊..
另外,这一行
add(komponent = new MyComponent());
在我看来看起来像是麻烦的根源。把它分成 2 个。