Flickerfree JPanel ???
Jeg har lavet et overvågningsprogram med input fra parallelporten, som skal gøres grafisk for brugeren.Jeg har et JPanel hvorpå der er tegnet et billede (test.gif) og en række linier (ca 5000 korte linier). Disse ting er statiske.
Så har jeg, på samme JPanel, en række linier forholdsvis få (50-100 stk også korte) der er dynamiske, som skal have ændret farve ca 5 gange i sekundet alt efter overågningens input. Overvågningen kører i sin egen tråd.
Hvordan får jeg lavet en grafisk fremstilling der ikke "blinker" ved hver opdatering.
Jeg har for en god ordens skyld placeret hele JPanel-baggrunden i en JScrollPane, da billedet kan skaleres/zoomes.
Jeg har forsøgt at lade den dynamiske del køre i sit eget JPanel og lægge det oven på det statiske, så jeg kun behøver at at lave opdateringen i det dynamiske JPanel. Men jeg kan ikke se det statiske panel igennem det dynamiske(eller omvendt), heller ikke med setOpaque(true). Er der en anden lignende løsning?
Følgende kode viser meget simplificeret min problemstilling. Det startes ved at køre musen ind over GUI'en.
Kan nogen ændre i min kode så der opnås en flickerfree GUI?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.image.*;
public class TestJPanel extends JFrame
{
Baggrund baggrund;
Random r = new Random();
Traad traad;
Vector statiskeStreger;
Vector dynamiskeStreger;
boolean startet = false;
public TestJPanel()
{
setSize(800,620);
setTitle("TestJPanel");
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension screenSize = toolkit.getScreenSize();
Dimension selfBounds = getSize();
setLocation((screenSize.width - selfBounds.width) / 2, (screenSize.height - selfBounds.height) / 2);
baggrund = new Baggrund();
baggrund.setLocation(0,0);
baggrund.addMouseListener(new Mus());
getContentPane().add(baggrund);
traad = new Traad();
statiskeStreger = new Vector();
for(int i=0; i<5000; ++i)
statiskeStreger.add(new Rectangle(randomNumber(20,760), randomNumber(20,560), randomNumber(20,760), randomNumber(20,560)));
dynamiskeStreger = new Vector();
for(int i=0; i<100; ++i)
dynamiskeStreger.add(new Rectangle(randomNumber(20,760), randomNumber(20,560), randomNumber(20,760), randomNumber(20,560)));
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public int randomNumber(int start, int slut)
{
if(start > slut)
return - 1;
return r.nextInt(slut-start) + start;
}
//inner class der tegnes på
public class Baggrund extends JPanel implements ImageObserver
{
public Baggrund()
{
super(true);
setSize(800,600);
}
public void paint(Graphics g)
{
super.paint(g);
Graphics2D g2 = (Graphics2D)g.create();
g2.setColor(new Color(255,255,255));
g2.fillRect(5,5,780,580);
g2.setColor(new Color(0,0,0));
g2.drawLine(10,10, 780,10);
g2.drawLine(10,10, 10,580);
g2.drawLine(780,10, 780,580);
g2.drawLine(10,580, 780,580);
ImageIcon image = new ImageIcon("test.gif");
g2.drawImage(image.getImage(),20, 20, 700, 500, this);
for(int i=0; i<statiskeStreger.size(); ++i)
{
Rectangle rec = (Rectangle)statiskeStreger.get(i);
g2.drawLine(rec.x, rec.y, rec.width, rec.height);
}
for(int i=0; i<dynamiskeStreger.size(); ++i)
{
g2.setColor(new Color(randomNumber(0,255),randomNumber(0,255),randomNumber(0,255)));
Rectangle rec = (Rectangle)dynamiskeStreger.get(i);
g2.drawLine(rec.x, rec.y, rec.width, rec.height);
}
}
public boolean imageUpdate(java.awt.Image billede, int nr2, int nr3, int nr4, int nr5, int nr6)
{
return false;
}
}
//inner class der starter tegningen
public class Mus extends MouseAdapter
{
public void mouseEntered(MouseEvent e)
{
if(!startet)//for at undgå exceptions efter start
traad.start();
}
}
//inner class der holder liv i tegningen
public class Traad extends Thread
{
public void run()
{
startet = true;
while(true)
{
try
{
baggrund.update(baggrund.getGraphics());
sleep(200);
}
catch(InterruptedException ie)
{}
}
}
}
public static void main(String args[])
{
TestJPanel testJPanel = new TestJPanel();
testJPanel.setVisible(true);
}
}
