------ Solution ---------------------------------------- ----
this multi -threaded redraw , what is your innovation ? Or ?
Java in , GUI thread is only one , but also from the concurrent safety speaking, is not allowed to access other threads casual Graphics' .
So multithreaded GUI system , are the only multi-threaded processing various types of data , or each on its own graphics buffer , and is ultimately responsible for the output to the screen , only the GUI thread .
landlord does not know what is expected of you ?
------ For reference only -------------------------------------- -
agree upstairs
------ For reference only -------------- -------------------------
can also be made of a single class of anonymous inner classes
------ For reference only ---------------------------------------
spend a lot of time drawing operation , the mouse may lose response , I want to use multiple threads drawing , so that can respond to mouse
------ For reference only --------- ------------------------------
------ For reference only ---------------------------------- -----
check the problem is not a method , or using too much memory
If you really think you can draw multiple threads of it, nor will it improve the current situation .
------ For reference only -------------------------------------- -
not a problem with the method is drawing operation takes time , during which the mouse will lose response , I should we do ?
------ For reference only -------------------------------------- -
drawing process can be drawn to the BufferedImage on the main thread is only responsible for the final synthesis and screen output.
------ For reference only -------------------------------------- -
" the process of drawing can be plotted on a BufferedImage "
still need to perform the process of drawing the thread ah
------ For reference only ------------------------- --------------
landlord heard of double buffering technique like what ? Similar but not exactly the same .
1st floor , as I said, you have to be able to distinguish the main GUI thread and other threads.
GUI main thread is responsible for controlling the output of the container , this is exclusive.
while other threads can draw the desired content to the respective BufferedImage drawn first , this period , BufferedImage is exclusively by the respective thread . I did not say the thread can not execute the drawing , I just emphasize the main GUI thread exclusivity .
Finally the main GUI thread regularly Buffered synthesis output to the main content of the container ( approximately equal to the screen ) , so the workload is very small GUI .
------ For reference only -------------------------------------- -
right, first GUI display again , to draw to BufferedImage, the last update to the interface .
If the interface corresponding BufferedImage more, to be able to use multiple threads to draw BufferedImage.
But the main GUI thread, which is only one .
------ For reference only -------------------------------------- -
way upstairs , I see not quite understand
I want to draw on the panel , if redraw call paint (), I opened a thread in the paint () in the thread to send the object and redraw event , redrawn in the thread , what do questions?
------ For reference only -------------------------------------- -
a multi-threaded C # examples redraw interface
http://topic.csdn.net/u/20120805/01/58230777-2767-4337-A8F8-A3725E7DB4B1.html
------ For reference only ------- --------------------------------
read your example , this Java are also supported. But so used directly , it should not be the solution to your problem :
javax.swing.SwingUtilities.invokeLater (doRun);
It is still in principle with the main GUI thread , if the Invoke the doRun computing is very complex, still blocking the GUI thread .
public class TestInvokeLater extends JFrame {
/**
* 负责绘图
*/
private Runnable doBusyDraw = new Runnable() {
public void run() {
try {
Thread.sleep(5000); // 每次绘图执行花 5 秒
} catch (InterruptedException e) {
}
System.out.println("BusyDraw done.");
}
};
/**
* 负责定时刷新
*/
private Thread refresher = new Thread() {
public void run() {
try {
while (true) {
SwingUtilities.invokeLater(doBusyDraw);
Thread.sleep(1000); // 每秒执行 1 次绘图
}
} catch (InterruptedException e) {
}
}
};
public TestInvokeLater() {
this.setSize(800, 600);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
JButton btnBusyDraw = new JButton("StartBusyDraw");
btnBusyDraw.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
refresher.start();
System.out.println("Thread started...");
}
});
this.add(btnBusyDraw);
}
/**
* 启动主函数
*/
public static void main(String[] args) {
TestInvokeLater wnd = new TestInvokeLater();
wnd.setVisible(true);
}
}
------ For reference only ----------------------------------- ----
" it is still in principle with the main GUI thread , if the Invoke the doRun operation is very complex, still blocking the GUI thread ."
I do not want to use the main GUI thread drawing , wanted to open a separate thread to perform drawing operations , it is difficult to be no way to do it ?
------ For reference only -------------------------------------- -
can , do not access controls, operating only Graphics.
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class MultiThreadDraw extends JFrame {
/**
* 窗体构造函数
*/
public MultiThreadDraw() {
this.setSize(800, 600);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
JButton btnStartThreads = new JButton("StartManyThread");
btnStartThreads.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Graphics g = ((JComponent) e.getSource()).getParent().getGraphics();
System.out.println(g.getClass());
for (int i = 0; i < 50; i++) {
new DrawWorker(g).start();
}
System.out.println("Thread started...");
}
});
this.getContentPane().add(btnStartThreads);
}
/**
* 启动主函数
*/
public static void main(String[] args) {
MultiThreadDraw wnd = new MultiThreadDraw();
wnd.setVisible(true);
}
private class DrawWorker extends Thread {
private Graphics g;
public DrawWorker(Graphics g) {
this.g = g;
}
public void run() {
Random rand = new Random();
while (true) {
g.setColor(new Color(rand.nextInt()));
g.drawString(String.valueOf(rand.nextInt()), rand.nextInt(800), rand.nextInt(600));
g.drawLine(rand.nextInt(800), rand.nextInt(600), rand.nextInt(800), rand.nextInt(600));
}
}
}
}
but still recommended to use BufferedImage, not all are drawn directly container Graphics
------ For reference only -------------------- -------------------
very grateful upstairs buddy !
buddy to code up and running very exciting !
for (int i = 0; i <50; i + +) {
new DrawWorker (g). start ();
}
I understand I do not know right ?
for loop every time a new thread, the thread has a while (true) loop will run until the program exits
construction of a thread , a thread starts running first , there is now a thread running
build the second thread , the second thread is running , there are two threads running
build the first three threads, the first three threads running , there are now three threads running
built the first four threads , the first four thread starts running , there are now four threads running
build the first five threads , the first five thread starts running , there are now five threads running
........
------ For reference only ---------------------------------- -----
understood correctly .
In fact, you can open the Task Manager, and then in the "View" - > "Select Columns" to increase the number of threads .
then a few more buttons , you can see the thread skyrocketing . . .
Note: The more the number of threads , the thread itself higher switching costs , the system slower . Finally if it is hundreds of threads with the GUI thread CPU resources to seize it , the interface will be the card .
------ For reference only -------------------------------------- -
Will there no other way ?
------ For reference only -------------------------------------- -
have ah , the worker thread to draw to BufferedImage , the main thread is responsible only for output.
are generally relatively recommend this :
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
import javax.swing.*;
public class BufferedImageGUI extends JFrame implements Runnable {
private volatile BufferedImage boardDrawing;
private volatile BufferedImage boardDisplaying;
/**
* 窗体构造函数
*/
public BufferedImageGUI() {
this.setSize(800, 600);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
boardDrawing = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_RGB);
boardDisplaying = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_RGB);
}
public void paint(Graphics g) {
g.drawImage(boardDisplaying, 0, 0, null);
}
public void run() {
Random rand = new Random();
while (true) {
// 复杂的绘制过程
Graphics g = boardDrawing.getGraphics();
g.clearRect(0, 0, boardDrawing.getWidth(), boardDrawing.getHeight());
for (int i = 0; i < 500; i++) {
g.setColor(new Color(rand.nextInt()));
g.drawString(String.valueOf(rand.nextInt()), rand.nextInt(800), rand.nextInt(600));
}
// 切换前景与背景工作区
BufferedImage tmp = boardDisplaying;
boardDisplaying = boardDrawing;
boardDrawing = tmp;
this.repaint();
// Sleep
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 启动主函数
*/
public static void main(String[] args) {
BufferedImageGUI wnd = new BufferedImageGUI();
wnd.setVisible(true);
new Thread(wnd).start();
}
}
------ For reference only ----------------------------------- ----
upstairs buddy nice to spend time to help me solve the problem , and this year more time precious ah !
compared the two methods , the first two kinds of feeling a little slower , it may also be selected depending on the application bar
Will there other ways?
------ For reference only -------------------------------------- -
in my limited knowledge , the no. . .
------ For reference only -------------------------------------- -
much to say, thanks buddy
------ For reference only --------------------------- ------------
Xie paste code that buddy child . . Multithreading is a very unhappy recently drawing , looking for a few days to see you a few codes , better than a few days before the silly efforts
------ For reference only ---------------------------------- -----
landlord you are too determined , and I see the post update , thought it was a new problem = _ =
------ For reference only ------ ---------------------------------
landlord heard of double buffering technique like what ? Similar but not exactly the same .
1st floor , as I said, you have to be able to distinguish the main GUI thread and other threads.
GUI main thread is responsible for controlling the output of the container , this is exclusive.
while other threads can draw the desired content to the respective BufferedImage drawn first , this period , BufferedImage is exclusively by the respective thread . I did not say the thread can not execute the drawing , I just emphasize the main GUI thread exclusivity .
Finally the main GUI thread regularly Buffered synthesis output to the main content of the container ( approximately equal to the screen ) , so the workload is very small GUI .
Hello , I understand what you mean , but I have a problem or do not understand : If I final output to the screen image is composed of three parts ( or more part ) , for example, is a game, we must first draw the map ( to create a mapping in its own thread within the thread BufferedImage1), then there is an obstacle equally drawn to a thread on its own BufferedImage2 , there is also a game characters to create a thread to draw to own BufferedImage3 , the last will BufferedImage1, BufferedImage2, BufferedImage, 3 by 1,2,3 priorities drawn to the main thread of the BufferedImage , and then re-exported , but the problem is that the execution of a thread needs to be processor , so draw there will be delay in operation or other error , but my game is dynamically updated picture of the next frame is drawn will not appear on the map and the current moment of the game in the game obstacles and characters in the game the next time the form it ?
没有评论:
发表评论