在 graphics2d 中使用 arrayList 作为 y 坐标
Using an arrayList as the y coordinate in graphics2d
我正在尝试通过使用 line2d/graphics2d 创建 "bar graph" 的形式来创建一种可视化数组排序的方法。这个想法是在 x 轴上有数组索引,然后在 y 上有值并在使用不同的排序方法时更新它。所以我尝试使用 arrayList 来存储 y 值,然后在 paint 方法中使用 for 循环绘制所有线条,但似乎每当我尝试使用 repaint 时它都会重置我的 arrayList,所以我该怎么做?
这是我使用的代码:
import javax.swing.*;
import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.Random;
public class Frame_Main extends JFrame {
private JPanel screen = new Screen();
private Screen _screen = new Screen();
private int rndMaxRange = 100;
private int maxArraySize = 50;
// TODO Make sure static is really needed
public static ArrayList<Integer> array = new ArrayList<>();
public Frame_Main() {
this.setSize(700, 500);
this.setVisible(true);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.add(screen);
}
public static void main(String[] args) {
Frame_Main m = new Frame_Main();
m.randomizeArray(array);
m.refreshVisuals(array);
}
public void refreshVisuals(ArrayList<Integer> arrayList) {
_screen.setArrayList(arrayList);
_screen.repaint();
System.out.println("Refreshed drawing. Screen Array Size: " + _screen.lineArrayList.size());
}
public void randomizeArray(ArrayList<Integer> arrayList) {
arrayList.clear();
Random rnd = new Random();
for (int i = 0; i < maxArraySize; i++) {
arrayList.add(rnd.nextInt(rndMaxRange) + 1);
}
System.out.println("Created an array with the size: " + arrayList.size());
}
}
class Screen extends JPanel {
public ArrayList<Integer> lineArrayList = new ArrayList<>();
// private int canvasWidth = Frame_Main.WIDTH;
private int lineWidth;
public void setArrayList(ArrayList<Integer> arrayList) {
lineArrayList.addAll(arrayList);
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
lineWidth = 3;
g2.setStroke(new BasicStroke(lineWidth));
System.out.println("lineArrayList Size: " + lineArrayList.size());
int x = 0;
for (int i : lineArrayList) {
g2.draw(new Line2D.Float(x, x, 0, i));
x = x + lineWidth;
}
}
}
您永远不会将 _screen 变量添加到 GUI,它永远不会显示,因此在其上调用 repaint()
不会执行任何操作。
所以首先,改变
this.add(screen);
至:
add(_screen);
其他不相关的问题:
- 您应该覆盖 JPanel 的 paintComponent 方法,而不是它的 paint 方法
- 您应该首先在覆盖中调用 super 的绘制方法。
例如,类似...
import java.awt.BasicStroke;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.*;
@SuppressWarnings("serial")
public class MyScreen extends JPanel {
private static final int PREF_W = 700;
private static final int PREF_H = 500;
private static final int LINE_WIDTH = 5;
private static final Stroke STROKE = new BasicStroke((float) LINE_WIDTH);
private static final int MAX_DATA_SIZE = 50;
private static final int MAX_RANGE = 400;
private List<Integer> displayData = new ArrayList<>();
private Random random = new Random();
public MyScreen() {
for (int i = 0; i < MAX_DATA_SIZE; i++) {
displayData.add(random.nextInt(MAX_RANGE) + 1);
}
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
@Override
protected void paintComponent(Graphics g) {
// to do house-keeping painting
super.paintComponent(g);
// to smooth out graphics
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (displayData == null) {
return;
}
g2.setStroke(STROKE);
int x = 0;
for (Integer i : displayData) {
g2.drawLine(x, x, 0, i);
x += LINE_WIDTH;
}
}
private static void createAndShowGui() {
MyScreen mainPanel = new MyScreen();
JFrame frame = new JFrame("My Screen");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
我正在尝试通过使用 line2d/graphics2d 创建 "bar graph" 的形式来创建一种可视化数组排序的方法。这个想法是在 x 轴上有数组索引,然后在 y 上有值并在使用不同的排序方法时更新它。所以我尝试使用 arrayList 来存储 y 值,然后在 paint 方法中使用 for 循环绘制所有线条,但似乎每当我尝试使用 repaint 时它都会重置我的 arrayList,所以我该怎么做?
这是我使用的代码:
import javax.swing.*;
import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.Random;
public class Frame_Main extends JFrame {
private JPanel screen = new Screen();
private Screen _screen = new Screen();
private int rndMaxRange = 100;
private int maxArraySize = 50;
// TODO Make sure static is really needed
public static ArrayList<Integer> array = new ArrayList<>();
public Frame_Main() {
this.setSize(700, 500);
this.setVisible(true);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.add(screen);
}
public static void main(String[] args) {
Frame_Main m = new Frame_Main();
m.randomizeArray(array);
m.refreshVisuals(array);
}
public void refreshVisuals(ArrayList<Integer> arrayList) {
_screen.setArrayList(arrayList);
_screen.repaint();
System.out.println("Refreshed drawing. Screen Array Size: " + _screen.lineArrayList.size());
}
public void randomizeArray(ArrayList<Integer> arrayList) {
arrayList.clear();
Random rnd = new Random();
for (int i = 0; i < maxArraySize; i++) {
arrayList.add(rnd.nextInt(rndMaxRange) + 1);
}
System.out.println("Created an array with the size: " + arrayList.size());
}
}
class Screen extends JPanel {
public ArrayList<Integer> lineArrayList = new ArrayList<>();
// private int canvasWidth = Frame_Main.WIDTH;
private int lineWidth;
public void setArrayList(ArrayList<Integer> arrayList) {
lineArrayList.addAll(arrayList);
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
lineWidth = 3;
g2.setStroke(new BasicStroke(lineWidth));
System.out.println("lineArrayList Size: " + lineArrayList.size());
int x = 0;
for (int i : lineArrayList) {
g2.draw(new Line2D.Float(x, x, 0, i));
x = x + lineWidth;
}
}
}
您永远不会将 _screen 变量添加到 GUI,它永远不会显示,因此在其上调用 repaint()
不会执行任何操作。
所以首先,改变
this.add(screen);
至:
add(_screen);
其他不相关的问题:
- 您应该覆盖 JPanel 的 paintComponent 方法,而不是它的 paint 方法
- 您应该首先在覆盖中调用 super 的绘制方法。
例如,类似...
import java.awt.BasicStroke;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.*;
@SuppressWarnings("serial")
public class MyScreen extends JPanel {
private static final int PREF_W = 700;
private static final int PREF_H = 500;
private static final int LINE_WIDTH = 5;
private static final Stroke STROKE = new BasicStroke((float) LINE_WIDTH);
private static final int MAX_DATA_SIZE = 50;
private static final int MAX_RANGE = 400;
private List<Integer> displayData = new ArrayList<>();
private Random random = new Random();
public MyScreen() {
for (int i = 0; i < MAX_DATA_SIZE; i++) {
displayData.add(random.nextInt(MAX_RANGE) + 1);
}
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
@Override
protected void paintComponent(Graphics g) {
// to do house-keeping painting
super.paintComponent(g);
// to smooth out graphics
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (displayData == null) {
return;
}
g2.setStroke(STROKE);
int x = 0;
for (Integer i : displayData) {
g2.drawLine(x, x, 0, i);
x += LINE_WIDTH;
}
}
private static void createAndShowGui() {
MyScreen mainPanel = new MyScreen();
JFrame frame = new JFrame("My Screen");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}