Avatar billede alister_crowley Nybegynder
14. februar 2005 - 12:54 Der er 17 kommentarer og
1 løsning

Paint metode overskriver alting ved fejl

Hej

Sidder her i sneen og leger med Java,
jeg er ved at lave et slags Paint program i java,
og det går meget godt.

Men jeg har et problem, når jeg aktivere min Paint metode, så overskriver den det hele med et usyneligt layer.
Og det samme hvis jeg tilføjer et ekstra panel.

Det jeg gerne vil er at når der klikkes på et Panel (TegneArea) så skal der tegnes en figur.
Men jeg kan ikke få det til at virker ordenlig.

Spørgmålet lyder så på, hvordan tilføjer jeg et panel (TegneArea) så jeg kan tegne på det via. Paint metoden ?

Koden indtil videre:

package paintpack;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.awt.Dimension;
import javax.swing.JLabel;
import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.Rectangle;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.ScrollPane;
import java.awt.Label;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.awt.Color;

public class JavaPaint extends JFrame
{

  int xPos;
  int yPos;
  int x;
  int y;
  int clicked;
  String figur = "cirkel";
  private JMenuItem menuHelpAbout = new JMenuItem();
  private JMenu menuHelp = new JMenu();
  private JMenuItem menuFileExit = new JMenuItem();
  private JMenu menuFile = new JMenu();
  private JMenuBar menuBar = new JMenuBar();
  private JPanel jPanel1 = new JPanel();
  private JButton ValgFirkant = new JButton();
  private JButton ValgCirkel = new JButton();

  public JavaPaint()
  {
    try
    {
      jbInit();
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }

  }
 
  public static void main(String[] args)
  {
    new JavaPaint();
  } 

  private void jbInit() throws Exception
  {
    this.setDefaultLookAndFeelDecorated(true);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setJMenuBar(menuBar);
    this.getContentPane().setLayout(null);
    this.setSize(new Dimension(584, 467));
    this.setTitle("JavaPaint");
    this.setBackground(new Color(252, 251, 255));
    this.getContentPane().setLayout(null);
    menuFile.setText("Fil");
    ValgFirkant.setText("Firkant");
    ValgFirkant.setBounds(new Rectangle(10, 370, 73, 23));
    ValgFirkant.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          ValgFirkant_actionPerformed(e);
        }
      });
    ValgCirkel.setText("Cirkel");
    ValgCirkel.setBounds(new Rectangle(95, 370, 75, 25));
    ValgCirkel.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          ValgCirkel_actionPerformed(e);
        }
      });
    menuFileExit.setText("Luk");
    menuFileExit.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent ae)
        {
          fileExit_ActionPerformed(ae);
        }
      });
    menuHelp.setText("Hjælp");
    menuHelpAbout.setText("Omkring JavaPaint");
    menuHelpAbout.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent ae)
        {
          helpAbout_ActionPerformed(ae);
        }
      });
    menuFile.add(menuFileExit);
    menuBar.add(menuFile);
    menuHelp.add(menuHelpAbout);
    menuBar.add(menuHelp);
    this.getContentPane().add(ValgCirkel, null);
    this.getContentPane().add(ValgFirkant, null);
    this.getContentPane().add(jPanel1, BorderLayout.CENTER);
    this.setDefaultLookAndFeelDecorated(true);

    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    Dimension frameSize = this.getSize();
    if (frameSize.height > screenSize.height)
    {
      frameSize.height = screenSize.height;
    }
    if (frameSize.width > screenSize.width)
    {
      frameSize.width = screenSize.width;
    }
    this.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);

    this.setVisible(true);
  }

  void fileExit_ActionPerformed(ActionEvent e)
  {
    System.exit(0);
  }

  void helpAbout_ActionPerformed(ActionEvent e)
  {
    JOptionPane.showMessageDialog(this, new JavaPaint_AboutBoxPanel1(), "Omkring JavaPaint", JOptionPane.PLAIN_MESSAGE);
  }
 
  /*
  // paintmetoden er dissablet pga. den overskrive hele layoutet.
  public void paint(Graphics g)
  {
    int width = 100;
    int height = 100;
    if(clicked == 1)
    {
      x = xPos - width/2;
      y = yPos - height/2;
      if(figur == "cirkel")
      {
        g.setColor(Color.green);
        g.fillOval(x,y,width,height);
      }
      if(figur == "firkant")
      {
        g.setColor(Color.red);
        g.fillRect(x,y,100,100);
      }   
      clicked = 0;
    }
  }
  */
 
  private void TegneArea_mouseClicked(MouseEvent e)
  {
    xPos = e.getX();
    yPos = e.getY();
    clicked = 1;
    repaint();
  }
 
 
  private void ValgCirkel_actionPerformed(ActionEvent e)
  {
    figur = "cirkel";
  }

  private void ValgFirkant_actionPerformed(ActionEvent e)
  {
    figur = "firkant";
  }

}
Avatar billede alister_crowley Nybegynder
14. februar 2005 - 16:13 #1
I princippet er det jeg vil at have paint() metoden til at tegne på et bestemt panel, jeg selv vælger, istedet for default.

Men jeg ved ikke hvordan.
Avatar billede mikkelbm Nybegynder
14. februar 2005 - 17:22 #2
Det smarteste vil efter min mening være at lave en klasse som extender et JPanel overskrive dens paintmetode og tilføje den til din JFrame.

Som det er nu, overskriver du JFrames paintmetode. Det vil sige at alt hvad du har tilføjet dertil ikke vil blive tegnet.
Derfor prøv følgende som det første i paintmetoden:

super.paint (g);

Altså:

public void paint(Graphics g)
{
    super.paint (g);
    int width = 100;
    int height = 100;
    // .....
}
Avatar billede alister_crowley Nybegynder
14. februar 2005 - 19:01 #3
wow, det hjalp utroligt meget.

Men lidt småændringer tegner den figurene nu, men kun en af gangen, og så slette den de gamle. Den kan også tegne ovenpå Knapperne og Menuen.

Mht. at lave en sekundær klasse og overskrive paintmetode, så kunne det da godt være en ide. Dog har jeg ikke den store ide om hvordan det skal gøres.

Kan jeg lokke et eksempel frem ?
Avatar billede mikkelbm Nybegynder
14. februar 2005 - 19:09 #4
Faktisk det samme som du gør nu bare extends JPanel i stedet. Det var bare en idé for at holde knapper adskilt fra selve 'tegnefladen'.

Og så have nogle metoder i det panel som gør det knapperne antyder.
Avatar billede alister_crowley Nybegynder
14. februar 2005 - 19:21 #5
øhh , man kan da ikke extende JPanel istedet for JFrame som virker programmet jo ikke mere ?
Avatar billede mikkelbm Nybegynder
14. februar 2005 - 19:27 #6
Du skal beholde din JFrame. Det jeg mener er blot at lave en ny klasse som extender JPanel og overskriver paint. I den klasse har du de metoder som gør de forskellige ting. Herefter tilføjer du den til din JFrame med:

getContentPane().add (ditPanel);

På den måde for du opdelt dit program mere logisk - fremfor at have det hele i en klasse.


Men du kan også sagtens bare gøre som du gør nu.
Avatar billede alister_crowley Nybegynder
14. februar 2005 - 19:40 #7
altså


PaintMetoder.java

imports java.atw.*; // osv....

public class PaintMetoder extends JPanel
{
  variabler
  public void paint(Graphics g)
  {
  // min paint-metode fra før
  }
}

men når jeg så vil tilføje med

this.getContentPane.add(PaintMetoder()); // eller bare PaintMetoder

så virker det ikke :(

Jeg kan ikke fortsætte med sådan som det virker nu , da den ikke beholder billederne, og stadig kan tegne ovenpå knapperne.
Avatar billede mikkelbm Nybegynder
14. februar 2005 - 20:05 #8
this.getContentPane.add(PaintMetoder());

skal nok være:

this.getContentPane.add(new PaintMetoder());

eller:

private PaintMetoder metoder;

// Constructor

metoder = new PaintMetoder ();

this.getContentPane().add (metoder);
Avatar billede mikkelbm Nybegynder
14. februar 2005 - 20:07 #9
Og jeg kan se du bruger nulllayout på din JFrame - så du skal også angive koordinater.

metoder.setBounde (new Rectangle (x, y, w, h));
Avatar billede alister_crowley Nybegynder
14. februar 2005 - 20:34 #10
fint, så mangler jeg bare at finde ud af hvordan jeg gør mine variable globale.

xPos og yPos og clicked skulle gerne gå med, da de bruges til at fortælle hvor den skal tegne figuren.
Avatar billede mikkelbm Nybegynder
14. februar 2005 - 20:37 #11
I dine actionmetoder:

private void TegneArea_mouseClicked(MouseEvent e)
  {
    xPos = e.getX();
    yPos = e.getY();
    clicked = 1;
    repaint();
  }
 
 
  private void ValgCirkel_actionPerformed(ActionEvent e)
  {
    figur = "cirkel";
  }

  private void ValgFirkant_actionPerformed(ActionEvent e)
  {
    figur = "firkant";
  }


Laver du kald ned til den nye klasse.

Noget a la:

private void TegneArea_mouseClicked(MouseEvent e)
  {
    metoder.metode1 (e.getX(), e.getY(), .....)
  }
 
  osv....
Avatar billede alister_crowley Nybegynder
14. februar 2005 - 20:44 #12
fint, så er alt næsten på plads :D

Mangler bare at den huske de gamle objekter, men det er vel bare at gemme dem i en vektor eller en buffer.

Jeg siger mange tak for hjælpen, og husk at ligge et svar :)
Avatar billede mikkelbm Nybegynder
14. februar 2005 - 20:47 #13
Du kan godt gemme det i en Vector eller en List af en form - alt afhængig af hvor meget du skal gemme.
Avatar billede mikkelbm Nybegynder
14. februar 2005 - 20:47 #14
Og et svar...
Avatar billede mikkelbm Nybegynder
14. februar 2005 - 20:48 #15
Når du siger objekter, går jeg ud fra du mener koordinater?
Avatar billede snoop_one Nybegynder
14. februar 2005 - 20:48 #16
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.Ellipse2D.Double;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class JavaPaint extends JFrame{

    int xPos;

    int yPos;

    int x;

    int y;

    int clicked;

    String figur = "cirkel";

    private JMenuItem menuHelpAbout = new JMenuItem();

    private JMenu menuHelp = new JMenu();

    private JMenuItem menuFileExit = new JMenuItem();

    private JMenu menuFile = new JMenu();

    private JMenuBar menuBar = new JMenuBar();

    private JPanel jPanel1 = new JPanel();

    private JButton ValgFirkant = new JButton();

    private JButton ValgCirkel = new JButton();

    private DrawCanvas dc;

    private Shape shape;

    private boolean cirkel_valgt;

    private boolean firkant_valgt;

    public JavaPaint() {
        try {
            jbInit();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        new JavaPaint();
    }

    private void jbInit() throws Exception {
        this.setDefaultLookAndFeelDecorated(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setJMenuBar(menuBar);
        this.setSize(new Dimension(584, 467));
        this.setTitle("JavaPaint");
        this.setBackground(new Color(252, 251, 255));
        cirkel_valgt = true;
        //lav et ny canvas
        dc = new DrawCanvas();
        //tilføje det til denne frame
        getContentPane().add(dc,BorderLayout.CENTER);
        //tilføj mouselistner
        dc.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                TegneArea_mouseClicked(e);

            }
        });
       
        menuFile.setText("Fil");
        ValgFirkant.setText("Firkant");
        ValgFirkant.setBounds(new Rectangle(10, 370, 73, 23));
        ValgFirkant.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                ValgFirkant_actionPerformed(e);
            }
        });
        ValgCirkel.setText("Cirkel");
        ValgCirkel.setBounds(new Rectangle(95, 370, 75, 25));
        ValgCirkel.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                ValgCirkel_actionPerformed(e);
            }
        });
        menuFileExit.setText("Luk");
        menuFileExit.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                fileExit_ActionPerformed(ae);
            }
        });
        menuHelp.setText("Hjælp");
        menuHelpAbout.setText("Omkring JavaPaint");
        menuHelpAbout.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                helpAbout_ActionPerformed(ae);
            }
        });
        menuFile.add(menuFileExit);
        menuBar.add(menuFile);
        menuHelp.add(menuHelpAbout);
        menuBar.add(menuHelp);
        JPanel bpanel = new JPanel();
       
        bpanel.add(ValgCirkel);
        bpanel.add(ValgFirkant);
        getContentPane().add(bpanel,BorderLayout.SOUTH);
       
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        Dimension frameSize = this.getSize();
        if (frameSize.height > screenSize.height) {
            frameSize.height = screenSize.height;
        }
        if (frameSize.width > screenSize.width) {
            frameSize.width = screenSize.width;
        }
        this.setLocation((screenSize.width - frameSize.width) / 2,
                (screenSize.height - frameSize.height) / 2);

        pack();
        this.setVisible(true);
       
    }

    void fileExit_ActionPerformed(ActionEvent e) {
        System.exit(0);
    }

    void helpAbout_ActionPerformed(ActionEvent e) {
        JOptionPane.showMessageDialog(this, new JFrame(), "Omkring JavaPaint",
                JOptionPane.PLAIN_MESSAGE);
    }

   
    private void TegneArea_mouseClicked(MouseEvent e) {
        if(cirkel_valgt){
            shape = new Ellipse2D.Double(e.getX(),e.getY(),50,50);   
        }
       
        else if(firkant_valgt){
            shape = new Rectangle2D.Double(e.getX(),e.getY(),50,50);
        }
        dc.setShape(shape);
        repaint();
    }

    private void ValgCirkel_actionPerformed(ActionEvent e) {
        cirkel_valgt = true;
        firkant_valgt = false;
    }

    private void ValgFirkant_actionPerformed(ActionEvent e) {
        firkant_valgt = true;
        cirkel_valgt = false;
    }
   
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;

import javax.swing.JPanel;

public class DrawCanvas extends JPanel {

    private Shape shape;
   
    public DrawCanvas(){
        super();
        setBackground(Color.WHITE);
    }
   
    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;
        if(shape!=null){
            g2d.draw(shape);
        }
    }
   
    public void setShape(Shape shape){
        this.shape = shape;
    }
}
Avatar billede alister_crowley Nybegynder
14. februar 2005 - 20:51 #17
ok

Og vil også kigge på dit eksempel snoop_one, tak for forslaget :)
Avatar billede alister_crowley Nybegynder
14. februar 2005 - 20:54 #18
med objekter, mente jeg de gamle tegninger, istedet for at der kun tegnes en af gangen :)
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