Avatar billede dresen Nybegynder
14. juli 2003 - 11:52 Der er 9 kommentarer og
1 løsning

Repaint i JFrame

Hej!

Jeg er i gang med at lave et skakspil, som jeg ønsker at repræsenterer grafisk. Dette har jeg forsøgt at gøre ved at have en klasse der arver fra JFrame, og som indeholder en paint metode.

Jeg har valgt at tegne mit skakbræt, ved at lave 64 kald til fillRect() metoden. Herefter foretager jeg kald til paintIcon() metoden, for at indsætte de forskellige brikker, som er repræsenteret vha. *.gif

Mit problem opstår, når brugeren skal foretage en handling(det skal siges at, det kun er tænkt som et to-player spil). Jeg har tilføjet en MouseListener til mit JFrame, så det er muligt for brugeren at klikke på skakbrættet, og kontrollerer også for, at der vælges områder inden for skakbrættets rammer. Men jeg er ikke i stand til at tegne noget nyt på brættet, som følge af en event.
Jeg har som test forsøgt et tegne en cirkel, på baggund af en user-event, ved brug af metoden drawOval og repaint(), men det lykkedes ikke for mig.
Avatar billede magoo20000 Nybegynder
14. juli 2003 - 13:17 #1
Ligende har været fremme her på Eksperten tidligere. Søg efter JFrame og repaint i fritekstsøgning.
Avatar billede _carsten Nybegynder
14. juli 2003 - 13:43 #2
Jeg tror ikke jeg helt forstår dit problem, så jeg har lavet et lille eksempel
som tegner cirkler hver gang musen slippes, måske kan det hjælpe dig på vej.


public class Draw extends javax.swing.JFrame {
   
    public Draw() {
        initComponents();
        setSize(400,400);
    }
   
    private void initComponents() {

        addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                drawCircle(evt);
            }
        });
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                exitForm(evt);
            }
        });

        pack();
    }

    private void drawCircle(java.awt.event.MouseEvent evt) {
        java.awt.Graphics g = this.getGraphics();
        java.awt.Graphics2D g2 = (java.awt.Graphics2D)g;
        g2.drawOval(evt.getX(), evt.getY(), 50,50);
    }

    private void exitForm(java.awt.event.WindowEvent evt) {
        System.exit(0);
    }
   
    public static void main(String args[]) {
        new Draw().show();
    }
}
Avatar billede _carsten Nybegynder
14. juli 2003 - 14:02 #3
Du behøver ikke at lave denne her, det er bare noget standard sjov jeg
plejer at gøre.

java.awt.Graphics2D g2 = (java.awt.Graphics2D)g;
Avatar billede dresen Nybegynder
14. juli 2003 - 14:34 #4
Tak for jeres svar.

carsten, de eksempler jeg har arbejdet ud fra, har været opbygget anderledes. Her har klassen som extender JFrame overskrevet paint-metoden.

Din opbygning virker en del flottere end ovenstående. Jeg kan dog stadig ikke helt finde ud af at løse mit problem. Hvis nu man vil tegne et rektangel som baggrund, og så tegne cirkler ovenpå vha. musen hvordan gør man så det (med udgangspunkt i din klasse Draw)?? Har prøvet med drawRect() i starten af din metode initComponents, men modtager nullPoinerException
Avatar billede _carsten Nybegynder
14. juli 2003 - 15:19 #5
Jeg er tidsmæssigt lidt presset, så jeg modificeret mit tidligere eksempel
lidt, skulle give dig en ide om hvordan det virker.

public class Draw extends javax.swing.JFrame {
   
    public Draw() {
        initComponents();
        setSize(400,400);
    }
   
    private void initComponents() {
        jPanel1 = new javax.swing.JPanel();
        jPanel2 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jComboBox1 = new javax.swing.JComboBox();

        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                exitForm(evt);
            }
        });

        jPanel1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                chooseDrawing(evt);
            }
        });

        getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER);

        jLabel1.setText("Tegn");
        jPanel2.add(jLabel1);

        jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Cirkel", "Rektangel" }));
        jPanel2.add(jComboBox1);

        getContentPane().add(jPanel2, java.awt.BorderLayout.NORTH);

        pack();
    }

    private void chooseDrawing(java.awt.event.MouseEvent evt) {
        if(jComboBox1.getSelectedIndex() == 0)
            drawCircle(evt);
        else
            drawRect(evt);
    }

    private void drawCircle(java.awt.event.MouseEvent evt) {
        java.awt.Graphics g = this.getGraphics();
        java.awt.Graphics2D g2 = (java.awt.Graphics2D)g;
        g2.drawOval(evt.getX(), evt.getY(), 50,50);
    } 
   
    private void drawRect(java.awt.event.MouseEvent evt) {
        java.awt.Graphics g = this.getGraphics();
        java.awt.Graphics2D g2 = (java.awt.Graphics2D)g;
        g2.setColor(java.awt.Color.YELLOW);
        g2.fillRect(evt.getX(), evt.getY(), 50,50);
        g2.setColor(java.awt.Color.BLACK);
    }

    private void exitForm(java.awt.event.WindowEvent evt) {
        System.exit(0);
    }

    public static void main(String args[]) {
        new Draw().show();
    }
   
    private javax.swing.JComboBox jComboBox1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
}
Avatar billede _carsten Nybegynder
14. juli 2003 - 15:22 #6
I øvrigt tror jeg du glemte at poste dit eksempel i din kommentar
kl. 14:34:04

Jeg synes i hvertfald der mangler noget.
Avatar billede dresen Nybegynder
14. juli 2003 - 15:55 #7
Hej carsten. Mange tak endnu en gang.

Jeg får ikke udtrykt mig klart nok, men har stadig stor glæde af at se din kode.

Jeg vil gerne kunne tegne i en container-component, ligesom du har vist mig i dine eksempler. Men samtidig vil jeg også gerne have det sådan, at der allerede er tegnet noget i feltet i forvejen (altså før brugeren har forårsaget en event). Med udgangspunkt i dit første Draw-eksempel kunne det foreksempel være, at der blev tegnet et stort rektangel, hvorefter man så kunne tegne cirkler ved klik på musen.

Jeg ville da tro, at man skulle kalde drawRect i metoden initComponents, men kan ikke få dette til at virke

swing.JFrame {
   
    public Draw() {
        initComponents();
        setSize(400,400);
    }
   
    private void initComponents() {

        java.awt.Graphics g = this.getGraphics();
        java.awt.Graphics2D g2 = (java.awt.Graphics2D)g;
        g2.fillRect(50, 50, 50, 50);

// etc.
// etc.

}
Håber at det giver lidt mere mening, ellers kan jeg prøve at præcisere yderligere. Vil meget gerne have hjælp, men jeg må opfordre til at du, prioterer mine spørgsmål lavere end din opgave. Vil meget gerne oprette et nyt spørgsmål, så du kan få flere point.

Tak for hjælpen
Avatar billede _carsten Nybegynder
14. juli 2003 - 18:15 #8
Flere point er ligegyldigt, men jeg for nok ikke tid før engang i morgen
har lige skimmet din kommentar - læser den igen i morgen
Avatar billede _carsten Nybegynder
14. juli 2003 - 20:58 #9
Fik lige lidt tid.

Det er rigtigt som du gør, du skal bare ændre lidt mere.
Grunden til at det ikke virker er metoden:  show();

Lav følgende ændringer:

    public Draw() {
        initComponents();
        setSize(400,400);

        show(); // KALD SHOW() HER, JFRAMEN SKAL VISES FØREND DU KAN
                // BEGYNDE AT TEGNE PÅ DEN
                // HUSK AT FJERNE show() FRA DEN STATISKE METODE
                //    public static void main(String args[]) {
                //        new Draw();        SÅDAN
                //    }

        java.awt.Graphics g = this.getGraphics();
        java.awt.Graphics2D g2 = (java.awt.Graphics2D)g;
        g2.fillRect(50, 50, 50, 50);
    }


Du kan også kalde min:      drawRect(java.awt.event.MouseEvent evt)
Det er bare noget mere tricky, for den mangler en MouseEvent som metoden
kræver som argument, den genereres ikke på det tidspunkt hvor din frame
initieres, det problem kan løses ved at du så at sige selv genererer en
mere eller mindre fiktiv MouseEvent, du kan ændre constructoren til
nedenstående, hvilket har samme effekt - ovenstående løsning er bare nemmest.

    public Draw() {
        initComponents();
        setSize(400,400);

        show();

        java.awt.event.MouseEvent mus =
                    new java.awt.event.MouseEvent(this,
                                                    0,
                                                    0,
                                                    0,
                                                    jPanel1.getX() + 50,
                                                    jPanel1.getY() + 50,
                                                    0,
                                                    true);
       
        drawRect(mus);
    }
Avatar billede dresen Nybegynder
24. juli 2003 - 12:26 #10
Hej Carsten.

Har ikke haft adgang til net, og har derfor ikke fået sagt tak for hjælpen. Har nu fået mit program til at virke, ved brug af dine råd.

Tak 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