使用Java Swing高效地重画线
我试图找到创建动态java图形应用程序的最有效方法。我想构建一个大屏幕,包含许多不同的部分,所有这些部分都使用不同的线程重新绘制或更新,这样屏幕看起来“生动”。 然而,我最初尝试这样做是可怕的,屏幕变得非常慢,有bug等等-所以我想我需要创建不同的模块(JPanel),每个模块都包含其他图形部分(线、圆等),并且每个不同的JPanel分别被重绘(需要时),而不是整个主面板(或框架) 所以我写了一个小的演示程序-我的程序包含一个窗口,多个面板,包装在我的对象“MyPanel”中-每个这样的MyPanel包含几条绘制的线(我有一个Line对象),所有线从左上角开始,具有不同的长度和角度)。每个不同的MyPanel都有不同的线条颜色(请参见此图) 我实例化了几个工作线程,每个线程指定用于一个MyPanel-工作线程等待5秒钟,然后尝试以以下方式重新绘制所有线条:使用Java Swing高效地重画线,java,swing,jpanel,Java,Swing,Jpanel,我试图找到创建动态java图形应用程序的最有效方法。我想构建一个大屏幕,包含许多不同的部分,所有这些部分都使用不同的线程重新绘制或更新,这样屏幕看起来“生动”。 然而,我最初尝试这样做是可怕的,屏幕变得非常慢,有bug等等-所以我想我需要创建不同的模块(JPanel),每个模块都包含其他图形部分(线、圆等),并且每个不同的JPanel分别被重绘(需要时),而不是整个主面板(或框架) 所以我写了一个小的演示程序-我的程序包含一个窗口,多个面板,包装在我的对象“MyPanel”中-每个这样的MyPa
- 从JPanel(MyPanel)中删除所有现有线路
- 创建具有不同角度和长度的新线
- 通过调用super.repaint()重新绘制JPanel(MyPanel)这就是全部目的,只更新此面板,让它用其所有子部分重新绘制自己,而不是整个程序
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* Displays the main windows (this is the "JFrame" object).
*/
public class GUI extends JFrame
{
/**
* A customized panel which contains several lines with different coordinates, all starting from
* the top left corner of the panel with coordinates (1,1). The object contains a method which
* removes all drawn lines from the panel, then redraws lines with different vectors.
*/
public static class MyPanel extends JPanel
{
private List<Line> _lines;
private Color _color;
private int _facet;
private int _numLines;
public MyPanel(int facet, int numLines, Color color)
{
_facet = facet;
_color = color;
_numLines = numLines;
_lines = new ArrayList<>();
super.setLayout(null);
createLines();
}
public void createLines()
{
for(Line line : _lines)
{
remove(line);
}
_lines.clear();
Random r = new Random();
for(int i = 0; i < _numLines; i++)
{
int lengthX = r.nextInt(_facet) + 1;
int lengthY = r.nextInt(_facet) + 1;
Line line = new Line(1, 1, 1 + lengthX, 1 + lengthY, 1, _color);
line.setBounds(1, 1, 1 + lengthX, 1 + lengthY);
super.add(line);
_lines.add(line);
}
super.repaint();
}
}
/**
* Represents a line, drawn with antialiasing at a given start and end coordinates
* and a given thickness.
*/
public static class Line extends JPanel
{
private int _startX;
private int _startY;
private int _endX;
private int _endY;
private float _thickness;
private Color _color;
public Line(int startX, int startY, int endX, int endY, float thickness, Color color)
{
_startX = startX;
_startY = startY;
_endX = endX;
_endY = endY;
_thickness = thickness;
_color = color;
}
public void paint(Graphics g)
{
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(_color);
g2d.setStroke(new BasicStroke(_thickness));
g2d.drawLine(_startX, _startY, _endX, _endY);
}
}
/**
* Stores all "MyPanel" panels of the GUI.
* The "MyPanels" are rectangular panels containing lines of the same color
* (different color across different panels).
*/
public List<MyPanel> panels;
public GUI()
{
setSize(800, 800);
setLayout(null);
setTitle("Y U no work??");
panels = new ArrayList<>();
// The starting positions (x,y) of the "MyPanel"s. All panels are squares of
// height = 300 and width = 300.
int[][] coords = {{1, 1}, {100, 100}, {200, 100}, {50, 300}, {300, 300},
{0, 400}, {300, 400}, {350, 250}, {370, 390}};
// The colors of the lines, drawn in the panels.
Color[] colors = {Color.RED, Color.GREEN, Color.BLUE, Color.ORANGE, Color.CYAN,
Color.MAGENTA, Color.YELLOW, Color.PINK, Color.darkGray};
for(int i = 0; i < colors.length; i++)
{
MyPanel panel = new MyPanel(300, 50, colors[i]);
panel.setBackground(new Color(0, 0, 0, 0));
// Set the *exact* start coordinates and width/height (null layout manager).
panel.setBounds(coords[i][0], coords[i][1], 300, 300);
add(panel);
panels.add(panel);
}
}
/**
* A runnable used to instantiate a thread which waits for 5 seconds then redraws
* the lines of a given "MyPanel".
*/
public static class Actioner implements Runnable
{
private MyPanel _panel;
public Actioner(MyPanel panel)
{
_panel = panel;
}
public void run()
{
while(true)
{
try
{
Thread.sleep(5000);
}
catch(Exception e) {}
_panel.createLines();
}
}
}
public static void main(String[] args)
{
GUI GUI = new GUI();
EventQueue.invokeLater(() ->
{
GUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GUI.setVisible(true);
});
// Create all operating threads (one per "MyPanel").
for(MyPanel panel : GUI.panels)
{
new Thread(new Actioner(panel)).start();
}
}
import java.awt.BasicStroke;
导入java.awt.Color;
导入java.awt.EventQueue;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.RenderingHints;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.Random;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
/**
*显示主窗口(这是“JFrame”对象)。
*/
公共类GUI扩展JFrame
{
/**
*一个自定义面板,其中包含多条具有不同坐标的线,所有线都从
*带有坐标(1,1)的面板左上角。该对象包含一个
*从面板中删除所有绘制的线,然后使用不同的矢量重新绘制线。
*/
公共静态类MyPanel扩展了JPanel
{
私有列表行;
私人色彩(u色),;
私人内部方面;
私人互联网;
公共MyPanel(整数面、整数线、彩色)
{
_小面=小面;
_颜色=颜色;
_numLines=numLines;
_行=新的ArrayList();
super.setLayout(空);
createLines();
}
公共void createLines()
{
对于(行:_行)
{
删除(行);
}
_行。清除();
随机r=新随机();
对于(int i=0;i<\u numLines;i++)
{
int lengthX=r.nextInt(_facet)+1;
int longlent=r.nextInt(_facet)+1;
线条=新线(1,1,1+长度,1+长度,1,_颜色);
线.立根(1,1,1+长度x,1+长度);
super.add(行);
_行。添加(行);
}
super.repaint();
}
}
/**
*表示在给定起点和终点坐标处使用抗锯齿绘制的线
*和给定的厚度。
*/
公共静态类行扩展了JPanel
{
私人int_startX;
私人国际机场;
私人互联网(endX);
私人国际;
专用浮子厚度;
私人色彩(u色),;
公共线(int startX、int startY、int endX、int endY、浮动厚度、颜色)
{
_startX=startX;
_startY=startY;
_endX=endX;
_endY=endY;
_厚度=厚度;
_颜色=颜色;
}
公共空间涂料(图g)
{
Graphics2D g2d=(Graphics2D)g;
g2d.setRenderingHint(renderingHits.KEY\u抗锯齿,renderingHits.VALUE\u抗锯齿\u开启);
g2d.setColor(_color);
g2d.设定行程(新基本行程(_厚度));
g2d.抽绳(_startX,_startY,_endX,_endY);
}
}
/**
*存储GUI的所有“MyPanel”面板。
*“MyPanels”是包含相同颜色线条的矩形面板
*(不同面板的颜色不同)。
*/
公开名单小组;
公共图形用户界面()
{
设置大小(800800);
setLayout(空);
片名(“你没有工作吗?”);
panels=newarraylist();
//“MyPanel”s的起始位置(x,y)。所有面板均为正方形
//高度=300,宽度=300。
int[][]coords={{1,1},{100100},{200100},{50300},{300300},
{0, 400}, {300, 400}, {350, 250}, {370, 390}};
//在面板中绘制的线条的颜色。
Color[]colors={Color.RED,Color.GREEN,Color.BLUE,Color.ORANGE,Color.CYAN,
Color.洋红,Color.YELLOW,Color.PINK,Color.darkGray};
for(int i=0;ipublic void paint(Graphics g)
{
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(_color);
g2d.setStroke(new BasicStroke(_thickness));
g2d.drawLine(_startX, _startY, _endX, _endY);
}
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(_color);
g2d.setStroke(new BasicStroke(_thickness));
g2d.drawLine(_startX, _startY, _endX, _endY);
g2d.dispose();
}
panel.setBackground(new Color(0, 0, 0, 0));
panel.setOpaque(false);
public void run()
{
while(true)
{
try
{
Thread.sleep(5000);
}
catch(Exception e) {}
_panel.createLines();
}
}