Avatar billede bootie Nybegynder
26. maj 2004 - 17:28 Der er 24 kommentarer og
1 løsning

Application med 2D grafik

Hej xperter.

Mit spørgsmål er umiddelbart simpelt.

Jeg har tidligere lavet 2d grafik i appletter, men skal du til at arbejde med det i en application. I appletten er der nogle funktioner der får billedet til at opdatere. Doublebuffering og sådan.
Hvis man fx skulle lave en application hvori der køre noget 2d grafik iform  af en eller anden slags spil, skal det panel der indeholder spillet jo gerne opdatere så tit som mulig og selve applicationen med knapper opdatere jo kun når der er ændringer eller noget i den stil.

Nogen der har en template til hvordan man starter på sådan en funktion eller nogle links til lige præcis det jeg beskriver?
Avatar billede Slettet bruger
26. maj 2004 - 21:22 #1
Der er faktisk ikke den store forskel på hvordan får en Applet og en Applikation udviklet, i bund og grund kan du bruge de samme komponenter i en applikation som du bruger i en Applet.
Forskellen ligger blot i hvordan man initialiserer en Applet i forhold til en applikation, desuden har du færre sikkerheds-restriktioner i en applikation end i en applet.
Mht. en konstant "refresh-rate" på et komponent kunne du jo med fordel programmere en tråd som opdatere din komponent hver 30. millisekund (som vil gi' dig en framerate på 30 fps).

Håber du kunne bruge mit svar til noget :-)
Avatar billede Slettet bruger
26. maj 2004 - 21:27 #2
Hvis du nu, f.eks brugte et Panel til at tegne på, kunne koden etc. se således ud:

class TestPanel extends Panel {
        private Thread painter;
       
        public void paint(Graphics g) {
            super.paint(g);           
        }
       
        public void startPainterThread() {
            painter = new Thread(new PaintThread(), "PainterThread");
            painter.start();
        }
       
        public void stopPainterThread() {
            painter = null;
        }
       
        class PaintThread implements Runnable {
            public void run() {
                while (Thread.currentThread() == painter) {
                    try {
                        TestPanel.this.repaint();
                        Thread.sleep(30);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }                   
                }
            }

        }
    }
Avatar billede Slettet bruger
26. maj 2004 - 21:28 #3
Din kode til at "tegne" skulle jo så bare ind i paint(Graphics)-metoden efter kaldet til super.paint(g);
Avatar billede bootie Nybegynder
26. maj 2004 - 22:12 #4
Ja, det kan meget vel være jeg forvirre mig selv mere end jeg behøves. Synes ikke at jeg i appletten skulle lave en tråd der tegnede billedet. Der skete det bare. Men det kan da være mig der husker forkert.

Kunne jeg lokke dig til at lave en application med et sort panel hvorpå man ligger et image hver gang tråden køre og så en knap i noget almindelig gui?
Avatar billede bootie Nybegynder
26. maj 2004 - 22:23 #5
Ja, nu ser jeg det. Jeg har en run i min applet der kalder en repaint(); som så ender med at kalde min paint(); der kalder min drawStuff();

Ja, men så er det jeg er i tvivl om vel om man i en application kan lave et panel der opdatere 30 gange i sekundet samtidig med man har almindelige javax.swing knapper?
Der er ingen diller daller problemer der?
Avatar billede Slettet bruger
26. maj 2004 - 22:24 #6
Noget i denne stil ?

import java.awt.*;
import java.awt.event.*;

public class TestApplication extends Frame {
    private TestPanel panel;
    private Button myButton;
   
    public TestApplication() {
        setLayout(new BorderLayout());
        add(panel = new TestPanel(), BorderLayout.CENTER);
        add(myButton = new Button("My neat button"), BorderLayout.SOUTH);
       
        myButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.out.println("The button was clicked upon, yay :-)");
            }
        });
       
        setSize(640, 480);
    }
   
    public static void main(String[] args) {
        TestApplication ta = new TestApplication();
        ta.show();
    }
}

class TestPanel extends Panel {
    private Thread painter;
 
    public void paint(Graphics g) {
        super.paint(g);         
    }
 
    public void startPainterThread() {
        painter = new Thread(new PaintThread(), "PainterThread");
        painter.start();
    }
 
    public void stopPainterThread() {
        painter = null;
    }
 
    class PaintThread implements Runnable {
        public void run() {
            while (Thread.currentThread() == painter) {
                try {
                    TestPanel.this.repaint();
                    Thread.sleep(30);
                } catch (Exception e) {
                    e.printStackTrace();
                }                 
            }
        }

    }
}
Avatar billede bootie Nybegynder
26. maj 2004 - 23:21 #7
hmmm...
Ja, lige præcis..
Nu prøver jeg dog at lave noget doublebuffering på testpanelet, men det vil ikke som jeg vil eller det vil ikke som det ville i min applet...

Der er en new TestPanel() i TestApplication() og i test prøver jeg at lave en Image offscreen og en Graphics gBuffer som i min applet, men det virker ikke.

class TestPanel extends Panel
{
    private Thread painter;
    private Graphics gBuffer;
    private Image offscreen;
    private Dimension dim;
   
    public TestPanel()
    {
        dim = getSize();
        offscreen = createImage(dim.width, dim.height);
        System.out.println("1");
        gBuffer = offscreen.getGraphics();
        System.out.println("2");
       
    }
...
Jeg for en NullPointerException ved gBuffer = offscreen.getGraphics(); selv om den jo egentlig burde at være initeret som den skal... jeg har stort set taget det lige ud af min applet.. burde det ikke virke? Eller er det rigtig nok at det skal det ikke?
Avatar billede Slettet bruger
26. maj 2004 - 23:29 #8
Det tror jeg så jeg har en forklaring på, altså hvorfor du får en NullPointerException...

Snippet (fra JavaDoc for Component, omhandlende createImage(xx,xx)-metoden)

Returns:
    an off-screen drawable image, which can be used for double buffering. The return value may be null if the component is not displayable. This will always happen if GraphicsEnvironment.isHeadless() returns true.

Måske burde du blot bruge klassen Toolkit til at oprette et Image-objekt med. Enten det, ellers kan du skifte til Swing-komponenter, de er pr. standard DoubleBuffered :-)
Avatar billede bootie Nybegynder
26. maj 2004 - 23:53 #9
Så jeg skal extende en JPanel istedet?
Avatar billede bootie Nybegynder
26. maj 2004 - 23:56 #10
Fx...
Hvor jeg så før ville tegne mit billede med:
        gBuffer.clearRect(0,0, dim.width, dim.height);
        gBuffer.setColor(Color.black);

Hvordan tegner jeg det så med et JPanel der allerede er doublebuffered?
Avatar billede Slettet bruger
27. maj 2004 - 09:44 #11
ja, extend bare med JPanel... der er sådan set ikke nogen stor forskel på at tegne med eller uden doublebuffering...

Der hvor du kalder:

offscreen = createImage(xx, xx);

hvorefter du tegner med det graphics-objekt du henter vha.

gBuffer = offscreen.getGraphics();

MEN, det du skal gøre er skrive dine grafiske kald i

public void paint(Graphics g) {
  super.paint(g);
  // Grafisk kald skal være her, istedet for til offscreen-image
}
Avatar billede bootie Nybegynder
27. maj 2004 - 09:53 #12
Måske jeg lige skulle få læst op på min swing og GUI viden igen...
Jeg synes godt nok at være lidt rusten
Avatar billede Slettet bruger
27. maj 2004 - 10:13 #13
Det tror jeg også, jeg kan bl.a. anbefale (swing):

http://java.sun.com/docs/books/tutorial/uiswing/learn/index.html
http://java.sun.com/docs/books/tutorial/uiswing/

Ovenstående er ikke dårlig arktikler, men en bog er da langt mere anbefalelsesværdig, hehe :-)
Avatar billede bootie Nybegynder
27. maj 2004 - 15:43 #14
Disse links kigge jeg igennem igår, men jeg synes ikke at nogle af dem fortalte noget som helst om hvordan man tegner 2DGraphics på en panel...
Eller om hvordan man tegner ting på et image og så smider det ind i sit panel.
Avatar billede Slettet bruger
27. maj 2004 - 18:44 #15
Det er så fordi de 2 links omhandler Swing, og ikke awt som indeholder klasserne Graphics samt Graphics2D.
Avatar billede bootie Nybegynder
27. maj 2004 - 18:46 #16
Så fik jeg endelig hul i den...
Jeg fattede åbenbart ikke lige det du mente med at jeg skulle tegne i paint.
Jeg VILLE bare have at jeg skulle tegne til et Image og så ligge det image ind i panelet.
Men nu køre det. Nu skriver har alt det den skal tegne i paint til g og det virker.
Det er da fedt.

Mange takker for tålmodigheden med mig
Avatar billede bootie Nybegynder
27. maj 2004 - 18:48 #17
Lige en ting dog.
Hvis jeg i min TestPanel laver et dim = getSize(); så bliver width og height = 0.
Men sætter jeg den ned i paint får de den rigtige størrelse.
Jeg troede da egentlig at den allerede ville kende sin størrelse når jeg laver objektet af TestPanel...
Avatar billede Slettet bruger
27. maj 2004 - 18:52 #18
Du vil først kunne få størrelsen på dit Panel efter den er blevet tildelt en størrelse, altså enten efter du har kaldt metoden setSize(xxx, xxx); eller kald metoden pack();

Det var så lidt, altså det med hjælpen... :-)
Avatar billede bootie Nybegynder
27. maj 2004 - 19:02 #19
Er der een eller anden setStartPosition(X,Y); således jeg skal se på at mit program starter oppe i venstre hjørne hele tiden?
Avatar billede bootie Nybegynder
27. maj 2004 - 19:03 #20
Det er efterhånden da en del spørgsmål jeg har fået kogt sammen i dette lille spørgsmål...
Vi finder ud af noget med nogle point
Avatar billede Slettet bruger
27. maj 2004 - 19:07 #21
ja, der findes en metode setPosition som enten tager to integers til parameter eller et Point-objekt... altså, hvis din frame skal starte i øverste venstre hjørne skal du kalde:

setPosition(0,0);
Avatar billede Slettet bruger
27. maj 2004 - 19:08 #22
hovsa, det er

setLocation(0,0);
Avatar billede bootie Nybegynder
27. maj 2004 - 19:11 #23
Jamen det er jo dejligt når man kan finde ud af det.
Jeg synes til tider at java docen kan være lidt uoverskuelig
Avatar billede Slettet bruger
27. maj 2004 - 20:34 #24
det er blot et spørgsmål om at tyde den, eller ha' en fornuftig IDE som inkorporerer en fornuftig mekanisme til at finde afsnit dokumentationen... med andre ord, IntelliJ IDEA er din ven :-)

Du giver mig bare de point du har lyst til, jeg er sådan set bare glad for at jeg har kunnet hjælpe dig med at løse dine problemer. Egentligt burde pointene afspejle hvor kompliceret et spørgsmål har været, og selvom der har været flere del-spørgsmål i dette, så har det alt sammen omhandlet de grafiske / GUI-komponenter i Java's API.

30 point er fin med mig :-)

Held og lykke på din videre java-færd, hehe

/Anders
Avatar billede bootie Nybegynder
27. maj 2004 - 22:30 #25
Endnu engang takker for hjælpen.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester