Avatar billede limes_planum Praktikant
18. august 2011 - 09:50 Der er 15 kommentarer og
1 løsning

Netbeans og Javax.swing.JFrame - At få kode i en class hægtet på GUI-styring i Netbeans

Jeg vil gerne kunne styre mit layout ( getContentPane() ) mere grafisk end ren kode. Det burde jeg kunne gøre i Netbeans med dets JFrame-opsætning.

Fra et tidligere spørgsmål: http://www.eksperten.dk/spm/945223?utm_source=qna&utm_medium=rss

- er jeg kommet frem til at blande koden fra en grafisk standard-opsætning af en JFrame og så en kode hvor jeg ved en 'onclick'-hændelse udskifter et billede:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

/**
*
* @author TD_DS_IS
*/
public class PicSwap extends javax.swing.JFrame {

    /** Creates new form f */
 

    /** This method is called from within the constructor to
    * initialize the form.
    * WARNING: Do NOT modify this code. The content of this method is
    * always regenerated by the Form Editor.
    */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 415, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>

    /**
    * @param args the command line arguments
    */    private JButton pic;
    private int ix;
    private String[] fnm = { "C:\\red.jpg", "C:\\green.jpg", "C:\\blue.jpg"};
    private void update() {
        pic.setIcon(new ImageIcon(fnm[ix]));
        ix = (ix + 1) % fnm.length;
    }
    public PicSwap() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("Picture swap");
        getContentPane().setLayout(new BorderLayout());
        pic = new JButton();
        pic.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                update();
            }
        });
        getContentPane().add(pic, BorderLayout.CENTER);
        ix = 0;
        update();
        pack();
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame f = new PicSwap();
                f.setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify
    // End of variables declaration
}

- - -

- problemet er så bare her at buildet ikke "lytter" til 'private void initComponents()'-klassen, hvori den grafiske længde og bredde defineres?
Avatar billede arne_v Ekspert
19. august 2011 - 00:07 #1
Kan du ikke bare kalde initComponents i constructoren?
Avatar billede limes_planum Praktikant
20. august 2011 - 00:18 #2
A la der her?:

    public PicSwap() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("Picture swap");

        getContentPane().setLayout(new initComponents());

        pic = new JButton();
        pic.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                update();
            }
        });
        getContentPane().add(pic, BorderLayout.CENTER);
        ix = 0;
        update();
        pack();
    }
Avatar billede limes_planum Praktikant
20. august 2011 - 00:28 #3
Har prøvet ovenstående uden held..

Er problemet ikke at min initComponents() er private der først og fremmest er en genereret kode? (jeg kan ikke editere den i Netbeans)

Vil ellers gerne gøre den class public så den kan ses/læses PicSwap..
Avatar billede arne_v Ekspert
20. august 2011 - 00:53 #4
public PicSwap() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("Picture swap");

        initComponents();

...
Avatar billede arne_v Ekspert
20. august 2011 - 00:54 #5
Men den rigtige loesning er nok at faa GUI builderen til at lave det samme som den manuelle kode goer.
Avatar billede limes_planum Praktikant
20. august 2011 - 09:18 #6
Ok - den her øvelse handler mest for mig om grundforståelse >> hvilket med lidt held betyder at jeg bygger det anderledes op fra start en anden gang..

Har lidt viden fra et dot.net-kursus omkring klasser (private, public og void) som jeg kan se kan bruges her.
Lige nu er målet bare at se, hvordan jeg kan få knappen til at være midt på et canvas/en flade som jeg selv har defineret størrelsen på.

- - -

    public PicSwap() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("Picture swap");
     
        initComponents();
      getContentPane().setLayout(??));
     
        pic = new JButton();
        pic.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                update();
            }
        });

      getContentPane().add(pic, BorderLayout.CENTER eller ??);

        ix = 0;
        update();
        pack();
    }

Jo når jeg kalder initComponents() som ovenstående, så udfolder jeg den rigtige størrelse for JFramen, men billederne er nu væk.

Er det ikke fordi at de to (skrevet med fed herover) ikke taler sammen med initComponents(), og hvordan kalder jeg initComponent ind i dem så både JFrame størrelse og billeder buildes?
Avatar billede arne_v Ekspert
20. august 2011 - 16:20 #7
Jeg tror at du skal droppe den initComponenets og selv styre din stoerrelse og layout.

getContentPane().setLayout(new BorderLayout());
...
getContentPane().add(pic, BorderLayout.CENTER);

placerer i midten.
Avatar billede limes_planum Praktikant
20. august 2011 - 16:46 #8
ok - hvordan gør jeg så fx baggrunden 500 bred og 300 høj?
Avatar billede arne_v Ekspert
20. august 2011 - 16:56 #9
Normalt angiver man sket ikke stoerrelsen af noget i Swing apps.

Det gaar galt naar brugeren resizer vinduet.
Avatar billede arne_v Ekspert
20. august 2011 - 16:57 #10
Swing opererer med de her layout managers, som godt kan vaer elidt tricky at forstaa.

Men proev og koer dette programm og leg lidt med at resize vinduet:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;

public class LayoutFun extends JFrame {
    public LayoutFun() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("LayoutFun");
        setPreferredSize(new Dimension(800, 600));
        getContentPane().setLayout(new GridLayout(2, 2));
        JPanel g11 = new JPanel();
        g11.setBorder(new EmptyBorder(5, 5, 5, 5));
        g11.setLayout(new BorderLayout());
        g11.add(new JLabel("BorderLayout"), BorderLayout.NORTH);
        JPanel g11body = new JPanel();
        g11body.setLayout(new BorderLayout());
        g11body.add(new JButton("North"), BorderLayout.NORTH);
        g11body.add(new JButton("South"), BorderLayout.SOUTH);
        g11body.add(new JButton("East"), BorderLayout.EAST);
        g11body.add(new JButton("West"), BorderLayout.WEST);
        g11body.add(new JButton("Center"), BorderLayout.CENTER);
        g11.add(g11body, BorderLayout.CENTER);
        getContentPane().add(g11);
        JPanel g12 = new JPanel();
        g12.setBorder(new EmptyBorder(5, 5, 5, 5));
        g12.setLayout(new BorderLayout());
        g12.add(new JLabel("GridLayout"), BorderLayout.NORTH);
        JPanel g12body = new JPanel();
        g12body.setLayout(new GridLayout(3, 3));
        for(int i = 1; i <= 9; i++) {
            g12body.add(new JButton("" + i));
        }
        g12.add(g12body, BorderLayout.CENTER);
        getContentPane().add(g12);
        JPanel g21 = new JPanel();
        g21.setBorder(new EmptyBorder(5, 5, 5, 5));
        g21.setLayout(new BorderLayout());
        g21.add(new JLabel("FlowLayout"), BorderLayout.NORTH);
        JPanel g21body = new JPanel();
        g21body.setLayout(new FlowLayout());
        for(int i = 1; i <= 9; i++) {
            g21body.add(new JButton("" + i));
        }
        g21.add(g21body, BorderLayout.CENTER);
        getContentPane().add(g21);
        JPanel g22 = new JPanel();
        g22.setBorder(new EmptyBorder(5, 5, 5, 5));
        g22.setLayout(new BorderLayout());
        g22.add(new JLabel("null layout"), BorderLayout.NORTH);
        JPanel g22body = new JPanel();
        g22body.setLayout(null);
        JButton btn2525 = new JButton("(25,25)");
        btn2525.setLocation(25, 25);
        btn2525.setSize(100, 40);
        g22body.add(btn2525);
        JButton btn7575 = new JButton("(75,75)");
        btn7575.setLocation(75, 75);
        btn7575.setSize(100, 40);
        g22body.add(btn7575);
        JButton btn125125 = new JButton("(125,125)");
        btn125125.setLocation(125, 125);
        btn125125.setSize(100, 40);
        g22body.add(btn125125);
        g22.add(g22body, BorderLayout.CENTER);
        getContentPane().add(g22);
        pack();
       
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame f = new LayoutFun();
                f.setVisible(true);
            }
        });
    }
}
Avatar billede limes_planum Praktikant
20. august 2011 - 17:47 #11
ok - kan se hvad du mener, da det hele scalerer med op og ned. Jeg har lige lånt et par bøger om Java, og tager det fra bunden af med dem nu, før jeg går videre (de har også nogle kapitler specifikt om grafik).

Læren af det her bliver nok at jeg ikke lige sådan umiddelbart kan GUI mig frem til at bruge en JFrame i Netbeans når jeg har som mål at skulle lave et brætspils-jar til en smartphone.

Netbeans genererer noget u-editerbart kode i dens GUI når jeg laver en JFrame derinde..

Men når jeg tænker over alle de forskellige mobilformater der er er det meget cool at kunne scalere det som i det sidste eksempel :)

Er egentlig ret godt tilfreds med svaret fra dig, da jeg er kommet en smule videre indsigtsmæssigt..
Avatar billede arne_v Ekspert
20. august 2011 - 19:05 #12
Normalt bruger jeg selv kun BorderLayout og GridLayout, men der er mere avancerede layout.

Du kan ogsaa i NetBeans  selv skrive al din GUI kode.

Hvis du med smartphone mener Android, saa bruger den slet ikke Swing.

Men saa vidt keg kan laese mig til saa bruger Android ogsa layout managers.
Avatar billede limes_planum Praktikant
21. august 2011 - 01:26 #13
Jeg må se om jeg kan overskue mig frem til en samlet løsning.
Der er i hvert fald så meget kød på dine forslag at det bør kunne bruges til at komme videre (kræver dog nok lidt held for mig personligt, men sikkert ikke for andre 'lidt mere øvede' der evt. kommer til at læse den her tråd fremover)..

- men iværdsætter grundigheden fra din side uanset, så smid et svar :)
Avatar billede limes_planum Praktikant
21. august 2011 - 01:31 #14
:-/ 'værdsætter'..
Avatar billede arne_v Ekspert
21. august 2011 - 03:21 #15
svar
Avatar billede arne_v Ekspert
21. august 2011 - 03:27 #16
http://developer.android.com/resources/articles/layout-tricks-efficiency.html

viser lidt om brug af layout manager i Android.

Anderledes at bruge fordi det er deklarativt XML ikke Java kode.

Men princippet i at bruge en layout manager maa vaere det samme.
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