Avatar billede netro Nybegynder
16. oktober 2005 - 17:46 Der er 27 kommentarer og
1 løsning

Layout af applet

Jeg har et problem med at få vist forskellige komponenter ovenpå en baggrund. De forsvinder ned under den. Jeg har lavet et eksempel på min kode her. Dvs. at det ikke er den rigtige, men det er samme fremgangsmåde, jeg benytter. Repaint() kalder jeg i forskellige timers, der ikke er vist her. Jeg har sikkert grebet det helt forkert an, men jeg er ikke så stiv i Javas GUI-design endnu.


public class MyClass extends JApplet {

  Container Pane;
  DrawingPanel DrawPanel;
  JPanel ControlPanel;
  JLabel Label1, Label2;
  Image bg1, bg2;
  Graphics bufferGraphics;
  Image offscreen;
  boolean bg;

  public void init() {
      Pane = getContentPane();
      DrawPanel = new DrawingPanel();
      Pane.add(DrawPanel);
      DrawPanel.setVisible(true);
      bg1 = getImage(getDocumentBase(), "bg1.jpg");
      bg2 = getImage(getDocumentBase(), "bg2.jpg");
  }

  public void start() {
  }

  public void paint(Graphics g) {
      bufferGraphics.clearRect(0, 0, this.getWidth(), this.getHeight());
      if(bg)
        bufferGraphics.drawImage(bg1, 0, 0, getBackground(), this);
      else
        bufferGraphics.drawImage(bg2, 0, 0, getBackground(), this);
  g.drawImage(offscreen, 0, 0, this);
  }

  public void update(Graphics g) {
      paint(g);
  }

  private class DrawingPanel extends JPanel {
      private DrawingPanel() {
        setLayout(new BorderLayout());
        ControlPanel = new JPanel();
        ControlPanel.setLayout(new GridLayout(1, 2));
        Label1 = new JLabel("", SwingConstants.CENTER);
        ControlPanel.add(Label1);
        Label2 = new JLabel("", SwingConstants.CENTER);
        ControlPanel.add(Label2);
        add(ControlPanel, BorderLayout.SOUTH);
      }
  }
}
Avatar billede mikkelbm Nybegynder
16. oktober 2005 - 17:49 #1
Prøv i din paint-metode at kalde:

super.paintComponents(g);

som det første.
Avatar billede netro Nybegynder
16. oktober 2005 - 17:51 #2
Ja, så vises det hele, men alt flimrer vildt.
Avatar billede mikkelbm Nybegynder
16. oktober 2005 - 17:53 #3
Hvad så med:

super.paintComponents(bufferGraphics);
Avatar billede netro Nybegynder
16. oktober 2005 - 17:56 #4
Så forsvinder baggrunden...
Avatar billede mikkelbm Nybegynder
16. oktober 2005 - 18:16 #5
Hmm... Det lyder underligt. Jeg prøver lige at lave et eksempel.
Avatar billede netro Nybegynder
16. oktober 2005 - 18:24 #6
Tak skal du have.
Avatar billede mikkelbm Nybegynder
16. oktober 2005 - 18:48 #7
Jeg kom lige til at tænke på en ting: Dit baggrundsbillede, skal det fylde hele skærmen hvor du så har nogle knapper eller labels ovenpå?

For så tror jeg ikke du kan bruge paintmetoden til det. Så vidt jeg husker, så kan du godt tegne ovenpå dine komponenter, men komponenterne kan ikke tegnes ovenpå noget andet - uden at det er gennemsigtigt.
Avatar billede netro Nybegynder
16. oktober 2005 - 18:52 #8
Ja, det skal det. Idéen er så, at jeg gerne vil have nogle labels og knapper til at ligge permanent ovenpå det i bunden. Men samtidig skal jeg kunne skifte dette baggrundsbillede efter behov. Det virkede faktisk, da jeg lavede det som en applikation - men der er måske forskelle i opførslen.

Hvad er dit forslag så?
Avatar billede mikkelbm Nybegynder
16. oktober 2005 - 18:54 #9
Der burde ikke være forskel på det. Jeg prøver lige at bikse et brugbart eksempel sammen.
Avatar billede netro Nybegynder
16. oktober 2005 - 18:55 #10
En løsning er måske også at opsplitte vinduet i to dele. Den nederste til et kontrolpanel (med knapper osv.) og den øverste til billederne og anden grafik der skal tegnes ovenpå billederne. Men jeg ved ikke lige, hvordan det skulle laves med et GridLayout.
Avatar billede mikkelbm Nybegynder
16. oktober 2005 - 18:58 #11
Det er nok den bedste løsning, ja. Det andet bliver i mine øjne lidt rodet - og ikke nødvendigt. Er det et must at du skal bruge GridLayout til det?
Avatar billede netro Nybegynder
16. oktober 2005 - 19:00 #12
Overhovedet ikke. Jeg er sådan set ligeglad, hvordan det udformes. Bare mine basale krav kan opfyldes. Dvs. et kontrolpanel nederst, der fylder ca 15% af højden og så et tegneområde øverst, hvor jeg kan tilføje billeder i flere lag.
Avatar billede mikkelbm Nybegynder
16. oktober 2005 - 19:02 #13
Okay... Så tror jeg efterhånden jeg kan lave et eksempel på det :)
Avatar billede netro Nybegynder
16. oktober 2005 - 19:03 #14
Fint!
Avatar billede mikkelbm Nybegynder
16. oktober 2005 - 19:25 #15
Så fik jeg tid til det...

Det er egentlig meget simpelt. Jeg har lavet det som en JFrame, da det var nemmere at teste...

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;

public class MyClass extends JFrame
{
    private Screen screen;
    private ControlPanel controlPanel;
   
    public MyClass ()
    {
        setSize (400, 600);
       
        screen = new Screen (new ImageIcon ("bg1.jpg").getImage());
        controlPanel = new ControlPanel (screen);
       
        this.getContentPane().add(screen, BorderLayout.CENTER);
        this.getContentPane().add(controlPanel, BorderLayout.SOUTH);
    }
   
    private class ControlPanel extends JPanel
    {
        private JButton buttonStart = new JButton("Start");
        private JButton buttonStop = new JButton("Stop");
        private Screen screen;
       
        public ControlPanel (final Screen screen)
        {
            this.screen = screen;
           
            this.add(buttonStart);
            this.add(buttonStop);
           
            buttonStart.addActionListener(new ActionListener()
            {
                public void actionPerformed (ActionEvent e)
                {
                    screen.start();
                }
            });
           
            buttonStop.addActionListener(new ActionListener()
            {
                public void actionPerformed (ActionEvent e)
                {
                    screen.stop();
                }
            });
        }
    }
   
    private class Screen extends JPanel implements Runnable
    {
        int width = 15;
        int currentX = 0;
        boolean running;
        Image background;
        Image offScreen;
        Graphics buffer;
        Thread thread;
       
        public Screen (Image background)
        {
            this.background = background;
           
            offScreen = new BufferedImage (400, 400, BufferedImage.TYPE_INT_ARGB);
            buffer = offScreen.getGraphics();
        }
       
        public void start ()
        {   
            running = true;
            if (thread == null)
            {
                thread = new Thread (this);
                thread.start();
            }
        }
       
        public void stop ()
        {
            running = false;
        }
       
        public void run ()
        {
            while (true)
            {
                if (running)
                {
                    if (currentX > this.getWidth())
                        currentX = 0;
                       
                    currentX++;
                       
                    repaint ();   
                }
               
                try
                {
                    Thread.sleep(10);
                }
                catch (Exception e) {}
            }
        }
       
        public void paint (Graphics g)
        {
            buffer.drawImage(background, 0, 0, this);
            buffer.fillRect(currentX, 200, width, width);
           
            g.drawImage(offScreen, 0, 0, this);
        }
    }
   
    public static void main (String[] args)
    {
        new MyClass().setVisible(true);
    }
}
Avatar billede mikkelbm Nybegynder
16. oktober 2005 - 19:28 #16
Og som applet (faktisk det samme):

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;

public class MyClass extends JApplet
{
    private Screen screen;
    private ControlPanel controlPanel;
   
    public void init ()
    {
        setSize (400, 600);
       
        screen = new Screen (getImage(getDocumentBase(), "bg1.jpg"));
        controlPanel = new ControlPanel (screen);
       
        this.getContentPane().add(screen, BorderLayout.CENTER);
        this.getContentPane().add(controlPanel, BorderLayout.SOUTH);
    }
   
    private class ControlPanel extends JPanel
    {
        private JButton buttonStart = new JButton("Start");
        private JButton buttonStop = new JButton("Stop");
        private Screen screen;
       
        public ControlPanel (final Screen screen)
        {
            this.screen = screen;
           
            this.add(buttonStart);
            this.add(buttonStop);
           
            buttonStart.addActionListener(new ActionListener()
            {
                public void actionPerformed (ActionEvent e)
                {
                    screen.start();
                }
            });
           
            buttonStop.addActionListener(new ActionListener()
            {
                public void actionPerformed (ActionEvent e)
                {
                    screen.stop();
                }
            });
        }
    }
   
    private class Screen extends JPanel implements Runnable
    {
        int width = 15;
        int currentX = 0;
        boolean running;
        Image background;
        Image offScreen;
        Graphics buffer;
        Thread thread;
       
        public Screen (Image background)
        {
            this.background = background;
           
            offScreen = new BufferedImage (400, 400, BufferedImage.TYPE_INT_ARGB);
            buffer = offScreen.getGraphics();
        }
       
        public void start ()
        {   
            running = true;
            if (thread == null)
            {
                thread = new Thread (this);
                thread.start();
            }
        }
       
        public void stop ()
        {
            running = false;
        }
       
        public void run ()
        {
            while (true)
            {
                if (running)
                {
                    if (currentX > this.getWidth())
                        currentX = 0;
                       
                    currentX++;
                       
                    repaint ();   
                }
               
                try
                {
                    Thread.sleep(10);
                }
                catch (Exception e) {}
            }
        }
       
        public void paint (Graphics g)
        {
            buffer.drawImage(background, 0, 0, this);
            buffer.fillRect(currentX, 200, width, width);
           
            g.drawImage(offScreen, 0, 0, this);
        }
    }
   
    public static void main (String[] args)
    {
        new MyClass().setVisible(true);
    }
}
Avatar billede netro Nybegynder
16. oktober 2005 - 19:31 #17
Den må jeg lige tygge lidt på. Tak indtil videre.
Avatar billede netro Nybegynder
17. oktober 2005 - 19:10 #18
Hej igen,

Det virker fint - grunden til det ikke fungerede for mig, var vist egentlig bare, at paint()-metoden lå uden for panelet.

Baggrunden flimrer heller ikke, men til gengæld er de bevægende objekter begyndt at hakke ift. før. Firkanten i dit eksempel kørte også lidt i ryk på min pc. Nogen idé om hvad det kan skyldes? Før var CPU-forbruget på ca. 40% - nu er det på 100%, og jeg har ikke ændret i nogle timere.
Avatar billede mikkelbm Nybegynder
17. oktober 2005 - 22:49 #19
Så fik jeg lidt tid igen. Jeg tror muligvis fejlen kan ligge i den måde jeg laver offscreen image på.

I stedet for:

offScreen = new BufferedImage (400, 400, BufferedImage.TYPE_INT_ARGB);

så prøv:

offScreen = new BufferedImage (400, 400, BufferedImage.TYPE_INT_RGB);

Der er ingen grund til at baggrundsbilledet kører alpha :)
Avatar billede mikkelbm Nybegynder
17. oktober 2005 - 22:52 #20
Efter en lille hurtig test, kan jeg konstatere at det på min maskine kører bedre blot med RGB i stedet for ARGB. Jeg var ikke lige opmærksom på, at det var så krævende at køre med den type.
Avatar billede netro Nybegynder
17. oktober 2005 - 23:24 #21
Det hjalp desværre ikke så meget her - den bruger stadig omkring 100%.
Avatar billede mikkelbm Nybegynder
18. oktober 2005 - 08:23 #22
Hmm... Så er jeg ved at være blank. Det hjalp godt nok her, men det var måske rent held :)

Kører jeg det i en almindelig applikation (JFrame) så virker det uden problemer, men kører jeg det i en applet, så har du ret i at det kører lidt i hak (dog bedre ved mig, da jeg skiftede til RGB).

Jeg har ikke de helt store erfaringer med applets, og jeg ved desværre ikke om det er en egenskab ved dem, at de opfører sig anderledes end almindelige applikationer, når det kommer til det grafiske.
Avatar billede netro Nybegynder
18. oktober 2005 - 15:09 #23
Nej okay, jeg roder selv lidt videre med det. Men mange tak for hjælpen! Læg gerne et svar.
Avatar billede mikkelbm Nybegynder
18. oktober 2005 - 15:12 #24
Det kommer her...
Avatar billede mikkelbm Nybegynder
18. oktober 2005 - 15:13 #25
Hvad hvis du kører det i en almindelig applikation? Altså nedarver fra en JFrame i stedet for JApplet - kører det så ikke udmærket?
Avatar billede netro Nybegynder
18. oktober 2005 - 15:14 #26
Det gjorde jeg først, og det kørte udmærket. Men det skal være en applet...
Avatar billede mikkelbm Nybegynder
18. oktober 2005 - 15:16 #27
Ja, okay. Det var også bare for lige at tjekke, det ikke kun var ved mig, situationen var sådan :)
Avatar billede netro Nybegynder
18. oktober 2005 - 15:17 #28
Nej, den er vist god nok - men det kører dog en smule bedre uden alphakanal :)
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