使用 Java 图形的数字线 API
Number Line using Java Graphics API
我正在尝试创建一个标有 x-axis.Two 问题的数轴:
- 0-9 一切正常。但在那之后,数字会被挤在一起,并且在比例上没有正确定位。
- 每次我尝试最大化我的 window 时我的主轴线往往会消失,或者有时它不会出现在 all.Every 任何这些发生时,我必须重新编译我的代码,它工作得很好。
对于上述问题的任何帮助将不胜感激。
import java.awt.Graphics;
import javax.swing.JFrame;
/**
* @author Emil Shirima
*
*/
public class Drawing extends JFrame {
/**
* @param args
*/
int width = 300, height = 300, spacing = 10;
int x1 = 0, y1 = 150, x2 = 300, y2 = 150;
public Drawing() {
setTitle("Trial");
setSize(width, height);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
@Override
public void paint(Graphics brush) {
brush.drawLine(x1, y1, x2, y2);
x1 = 10;
y1 = 150;
x2 = 10;
y2 = 130;
// brush.drawLine(x1, y1, x2, y2);
for (int i = 0; i < 12; ++i) {
String ID = Integer.toString(i);
x1 = x2 += spacing;
brush.drawLine(x1, y1, x2, y2);
if (i < 10) {
brush.drawString(ID, x1 - 3, y2 + 40);
} else {
// With the below implementation, the numbers overlap each other
// and are not properly oriented on the axis
brush.drawString(ID, x1 - 3, y2 + 40);
// TODO: I need to resize the numbers after 10 so as they fit
// properly on the scale
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Drawing draw_object = new Drawing();
}
当前实施:
最大化 GUI:
您的主要问题:
- 您在绘画方法中更改了 x1、x2,这些更改将在下一次绘画中保留。换句话说,您是在渲染方法中更改对象的状态,这是您必须避免的事情。
- 您使用的 "magic" 数字使您的程序难以调试。
其他相关问题:
- 您直接在 JFrame 中绘图,Swing 绘图教程告诉您绝对不要这样做,因为存在严重副作用的风险。
- 改为在 JPanel 的 paintComponent 方法中绘制。
- 你没有调用任何超级绘画方法,因此打破了绘画链。
如果您希望数字线延伸穿过组件,请在绘制方法(同样是 paintComponent)中获取组件的大小,并使用它来帮助确定线的位置。
还可以考虑添加一些 FontMetrics 来帮助放置数字文本。例如,以下代码创建一个可实现的数字行:
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import javax.swing.*;
@SuppressWarnings("serial")
public class SimpleNumberLinePanel extends JPanel {
private static final int PREF_W = 800;
private static final int PREF_H = 300;
private static final int GAP = 10;
private static final int START = 0;
private static final int END = 12;
private static final int VERT_LINE_HEIGHT = 20;
private static final Font FONT = new Font(Font.MONOSPACED, Font.BOLD, 14);
private static final int TEXT_GAP = 2;
@Override
protected void paintComponent(Graphics g) {
// call super method
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
// initialize these guys each time paintComponent is called
int x1 = GAP;
int y1 = height / 2;
int x2 = width - 2 * GAP;
int y2 = y1;
g.drawLine(x1, y1, x2, y2);
for (int i = START; i <= END; i++) {
int x = (i * (x2 - x1)) / (END - START) + GAP;
drawNumberAndLine(g, i, x, y1, VERT_LINE_HEIGHT);
}
}
private void drawNumberAndLine(Graphics g, int number, int x, int y,
int vertLineHeight) {
int x1 = x;
int y1 = y;
int x2 = x;
int y2 = y - vertLineHeight;
g.drawLine(x1, y1, x2, y2);
String text = String.valueOf(number);
g.setFont(FONT);
FontMetrics fontMetrics = g.getFontMetrics();
int textX = x - fontMetrics.stringWidth(text) / 2;
int textY = y + fontMetrics.getHeight() + TEXT_GAP;
g.drawString(text, textX, textY);
}
@Override // make GUI bigger
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Number Line");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new SimpleNumberLinePanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
我正在尝试创建一个标有 x-axis.Two 问题的数轴:
- 0-9 一切正常。但在那之后,数字会被挤在一起,并且在比例上没有正确定位。
- 每次我尝试最大化我的 window 时我的主轴线往往会消失,或者有时它不会出现在 all.Every 任何这些发生时,我必须重新编译我的代码,它工作得很好。
对于上述问题的任何帮助将不胜感激。
import java.awt.Graphics;
import javax.swing.JFrame;
/**
* @author Emil Shirima
*
*/
public class Drawing extends JFrame {
/**
* @param args
*/
int width = 300, height = 300, spacing = 10;
int x1 = 0, y1 = 150, x2 = 300, y2 = 150;
public Drawing() {
setTitle("Trial");
setSize(width, height);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
@Override
public void paint(Graphics brush) {
brush.drawLine(x1, y1, x2, y2);
x1 = 10;
y1 = 150;
x2 = 10;
y2 = 130;
// brush.drawLine(x1, y1, x2, y2);
for (int i = 0; i < 12; ++i) {
String ID = Integer.toString(i);
x1 = x2 += spacing;
brush.drawLine(x1, y1, x2, y2);
if (i < 10) {
brush.drawString(ID, x1 - 3, y2 + 40);
} else {
// With the below implementation, the numbers overlap each other
// and are not properly oriented on the axis
brush.drawString(ID, x1 - 3, y2 + 40);
// TODO: I need to resize the numbers after 10 so as they fit
// properly on the scale
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Drawing draw_object = new Drawing();
}
当前实施:
最大化 GUI:
您的主要问题:
- 您在绘画方法中更改了 x1、x2,这些更改将在下一次绘画中保留。换句话说,您是在渲染方法中更改对象的状态,这是您必须避免的事情。
- 您使用的 "magic" 数字使您的程序难以调试。
其他相关问题:
- 您直接在 JFrame 中绘图,Swing 绘图教程告诉您绝对不要这样做,因为存在严重副作用的风险。
- 改为在 JPanel 的 paintComponent 方法中绘制。
- 你没有调用任何超级绘画方法,因此打破了绘画链。
如果您希望数字线延伸穿过组件,请在绘制方法(同样是 paintComponent)中获取组件的大小,并使用它来帮助确定线的位置。
还可以考虑添加一些 FontMetrics 来帮助放置数字文本。例如,以下代码创建一个可实现的数字行:
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import javax.swing.*;
@SuppressWarnings("serial")
public class SimpleNumberLinePanel extends JPanel {
private static final int PREF_W = 800;
private static final int PREF_H = 300;
private static final int GAP = 10;
private static final int START = 0;
private static final int END = 12;
private static final int VERT_LINE_HEIGHT = 20;
private static final Font FONT = new Font(Font.MONOSPACED, Font.BOLD, 14);
private static final int TEXT_GAP = 2;
@Override
protected void paintComponent(Graphics g) {
// call super method
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
// initialize these guys each time paintComponent is called
int x1 = GAP;
int y1 = height / 2;
int x2 = width - 2 * GAP;
int y2 = y1;
g.drawLine(x1, y1, x2, y2);
for (int i = START; i <= END; i++) {
int x = (i * (x2 - x1)) / (END - START) + GAP;
drawNumberAndLine(g, i, x, y1, VERT_LINE_HEIGHT);
}
}
private void drawNumberAndLine(Graphics g, int number, int x, int y,
int vertLineHeight) {
int x1 = x;
int y1 = y;
int x2 = x;
int y2 = y - vertLineHeight;
g.drawLine(x1, y1, x2, y2);
String text = String.valueOf(number);
g.setFont(FONT);
FontMetrics fontMetrics = g.getFontMetrics();
int textX = x - fontMetrics.stringWidth(text) / 2;
int textY = y + fontMetrics.getHeight() + TEXT_GAP;
g.drawString(text, textX, textY);
}
@Override // make GUI bigger
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Number Line");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new SimpleNumberLinePanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}