Avatar billede jaffafo Nybegynder
25. december 2005 - 23:45 Der er 18 kommentarer og
1 løsning

Hjælp til Swing

Hej.. her er min kode (ikke helt min egen da jeg fik hjælp i et andet spørgsmål):

package talfinder;
import java.util.Random;
import java.util.ArrayList;
import java.util.List;

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

public class Main extends JFrame {
 
    public Main() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setLayout(new BorderLayout());
        List lst = talfinder();
        String streng = "Arraylisten indeholder " + lst.size() + " udtrukne tal.";
        JLabel antaltal = new JLabel(streng);
        String streng2 = "Udtrukne tal: " + talstreng(lst);
        JLabel tal = new JLabel(streng2);
        getContentPane().add(antaltal, BorderLayout.NORTH);
        getContentPane().add(tal, BorderLayout.SOUTH);
        pack();
    }

    public static void main(String[] args) {
        Main f = new Main();
        f.setVisible(true);
    }

    private static List talfinder() {
        // Talfinder (finder tal imellem 1 og 50)
        Random generator = new Random();
        List lst = new ArrayList();

        // Finder 5 tal mellem 1 og 50 og fyld det på arraylisten
        for (int i = 0; i < 5; i++) {
            int num1 = generator.nextInt(50) + 1;

            //smider det udtrukne tal "num1" i arraylisten
            lst.add(num1);
        }
        return lst;
    }
    private static String talstreng(List lst) {
        //skriver tal i arraylisten ud
        String indexnr = "";
        for (int i = 0; i < lst.size(); i++) {
            if(i > 0) indexnr += ",";
            indexnr += lst.get(i);
        }
        return indexnr;
    }
}

Koden kører perfekt, men jeg har lige nogle hurtige spørgsmål:

1. Hvordan sætter jeg en titel på vinduet? Jeg har prøvet med JFrame.setTitle("tekst"); men det funker ikke :/

2. Hvad er "extends Jframe" og hvordan fungerer det?
Avatar billede erikjacobsen Ekspert
26. december 2005 - 01:17 #1
1. og 2. hænger sammen. Din Main-klasse indeholder de samme metoder som JFrame. Derfor kan du i din
public Main constructor direkte skrive

  setTitle("tekst");

eller, hvis du synes det er mere præcist:

  this.setTitle("tekst");
Avatar billede jaffafo Nybegynder
26. december 2005 - 01:54 #2
Takker :)

troede bare bestemt jeg havde prøvet det uden succes, men jeg har nok stavet det forkert eller noget.. :/

Smider du et svar?
Avatar billede jaffafo Nybegynder
26. december 2005 - 02:28 #3
lige et lille spørgsmål mere:

Det kan ikke passe at det er så svært at placere ting på brugerfladen. Jeg har nu bøvlet i et par timer med JPanel, JFrame, Jthis og Jthat.. Er det svært at finde ud af eller er det mig der er helt forkert på den?

Mit arbejde hidtil:


    public Main() {
        //Sætter nogle options på JFrame
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setLayout(new BorderLayout());
        setTitle("Talfinder");
       
        //Declarer en liste og fylder den med tal fra talfinder() metoden
        List lst = talfinder();
       
        //Laver labels og fylder dem med data
        String streng = "Arraylisten indeholder " + lst.size() + " udtrukne tal.";
        JLabel antaltal = new JLabel(streng);
        String streng2 = "Udtrukne tal: " + talstreng(lst);
        JLabel tal = new JLabel(streng2);
        String streng3 = "Talfinder version: 0.1";
        JLabel version = new JLabel(streng3);
       
        //Sætter panelet og fylder det med strings
        JPanel topPanel = new JPanel();
        topPanel.setLayout( new BorderLayout() );
        topPanel.add(version, BorderLayout.SOUTH);
        topPanel.add(antaltal, BorderLayout.NORTH);
        topPanel.add(tal, BorderLayout.WEST);
        getContentPane().add(topPanel);
       
        //declare panel
        JPanel talfinderpanel = createYAxisPanel();
        topPanel.add(talfinderpanel, BorderLayout.CENTER);
       
        pack();
    }
   
    public JPanel createYAxisPanel()
    {
        JPanel panel = new JPanel();
        panel.setLayout( new BoxLayout( panel, BoxLayout.Y_AXIS ) );
        panel.setBackground( Color.BLUE );

        // Add some components to this panel
        panel.add( new JButton("Hent nye tal") );

        return panel;
    }


Det giver:
Avatar billede jaffafo Nybegynder
26. december 2005 - 02:29 #4
http://img483.imageshack.us/my.php?image=gcs01580jr.jpg

Hvilket jo ikke er særlig pænt.. :/
Avatar billede jaffafo Nybegynder
26. december 2005 - 04:17 #5
Og lige et spørgsmål mere ;)

Jeg tilføjer en button i Main() der hedder Knap (opfindsomt ;p)

Den nyeste kode:

package talfinder;
import java.util.Random;
import java.util.ArrayList;
import java.util.List;

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

public class Main extends JFrame {
 
    public Main() {
        //Sætter nogle options på JFrame
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setLayout(new BorderLayout());
        setTitle("Talfinder");
       
        //Sætter en button
        JButton knap = new JButton();
        knap.setText("Hent nye tal");
        knap.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                knap(evt);
            }
        });
       
        //Laver labels og fylder dem med data
        String streng = "Arraylisten indeholder " + talfinder().size() + " udtrukne tal.";
        JLabel antaltal = new JLabel(streng);
        String streng2 = "Udtrukne tal: " + talstreng(talfinder());
        JLabel tal = new JLabel(streng2);
        String streng3 = "Talfinder version: 0.1";
        JLabel version = new JLabel(streng3);
       
        //Sætter panelet og fylder det med strings
        JPanel topPanel = new JPanel();
        topPanel.setLayout(new GridLayout(4,1));
        getContentPane().add(topPanel);
        topPanel.add(knap);
        topPanel.add(antaltal);
        topPanel.add(tal);
        topPanel.add(version, BorderLayout.EAST);
        pack();
    }
   
    private void knap(java.awt.event.ActionEvent evt) {
       
    }
   
    public static void main(String[] args) {
        Main f = new Main();
        f.setVisible(true);
    }

    private static List talfinder() {
        // Talfinder (finder tal imellem 1 og 50)
        Random generator = new Random();
        List lst = new ArrayList();

        // Finder 5 tal mellem 1 og 50 og fyld det på arraylisten
        for (int i = 0; i < 5; i++) {
            int num1 = generator.nextInt(50) + 1;

            //smider det udtrukne tal "num1" i arraylisten
            lst.add(num1);
        }
        return lst;
    }
   
    private static String talstreng(List lst) {
        //skriver tal i arraylisten ud
        String indexnr = "";
        for (int i = 0; i < lst.size(); i++) {
            if(i > 0) indexnr += ",";
            indexnr += lst.get(i);
        }
        return indexnr;
    }
}

Hvordan kan jeg gøre det sådan at den ikke laver noget når jeg kører programmet, men når jeg så trykker på knappen
så skal den køre talfinder() og talstreng() og vise resultatet. Jeg forventer ingen færdig løsning.. bare et lille fingerpeg i den rigtige retning ville være godt :)

btw  hvad er forskelle på:
public Main()
og
public static void main(String[] args)??
Avatar billede arne_v Ekspert
26. december 2005 - 09:48 #6
public Main() er constructor til klassen Main

public static void main(String[] args) er main entry d.v.s. det som programmet starter med

og hvis du havde kaldt din klasse noget andet sp havde det været nemmere at
se forskellen
Avatar billede arne_v Ekspert
26. december 2005 - 09:55 #7
en lidt tilrettet version:

package december;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Main extends JFrame {
    private JLabel antaltal;
    private JLabel tal;
    private JLabel version;
   
    public Main() {
        //Sætter nogle options på JFrame
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setLayout(new BorderLayout());
        setTitle("Talfinder");
     
        //Sætter en button
        JButton knap = new JButton();
        knap.setText("Hent nye tal");
        knap.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                knapklik(evt);
            }
        });
     
        //Laver labels og fylder dem med data
        antaltal = new JLabel("");
        tal = new JLabel("");
        version = new JLabel("");
     
        //Sætter panelet og fylder det med strings
        JPanel topPanel = new JPanel();
        topPanel.setLayout(new GridLayout(4,1));
        getContentPane().add(topPanel);
        topPanel.add(knap);
        topPanel.add(antaltal);
        topPanel.add(tal);
        topPanel.add(version);
        pack();
    }
 
    private void knapklik(java.awt.event.ActionEvent evt) {
        String streng = "Arraylisten indeholder " + talfinder().size() + " udtrukne tal.";
        antaltal.setText(streng);
        String streng2 = "Udtrukne tal: " + talstreng(talfinder());
        tal.setText(streng2);
        String streng3 = "Talfinder version: 0.1";
        version.setText(streng3);
        pack();
    }
    public static void main(String[] args) {
        Main f = new Main();
        f.setVisible(true);
    }

    private static List talfinder() {
        // Talfinder (finder tal imellem 1 og 50)
        Random generator = new Random();
        List lst = new ArrayList();

        // Finder 5 tal mellem 1 og 50 og fyld det på arraylisten
        for (int i = 0; i < 5; i++) {
          int num1 = generator.nextInt(50) + 1;

          //smider det udtrukne tal "num1" i arraylisten
            lst.add(num1);
        }
        return lst;
    }
    private static String talstreng(List lst) {
        //skriver tal i arraylisten ud
        String indexnr = "";
        for (int i = 0; i < lst.size(); i++) {
            if(i > 0) indexnr += ",";
            indexnr += lst.get(i);
        }
        return indexnr;
    }
}
Avatar billede jaffafo Nybegynder
26. december 2005 - 22:42 #8
Takker mange gange.. det var perfekt :)


Lige et spørgsmål mere :)

Jeg har fjernet Pack(); så jeg kan lave vinduet større, så nu prøver jeg at lege lidt med dette:

JLabel version = new JLabel(streng3);
version.setLocation(20, 35);
version.setAlignmentY(40);

Men det hjælper ikke en pind... :/ Det jeg forsøger at gøre er at placere teksten i center og i bunden af dens "celle". Jeg har forsøgt mig med flere ting, men det er som om at noget forhindrer mig at ændre på placering af ting.. eller jeg gør det forkert ;)

Min kode nu:

package talfinder;
import java.util.Random;
import java.util.ArrayList;
import java.util.List;

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

public class Main extends JFrame {
    private JLabel antaltal;
    private JLabel tal;
    private JLabel klikviser;
    private static int klik = 0;

    public static final int X = 100; // JFrame left X coordinate
    public static final int Y = 10; // JFrame top Y coordinate
    public static final int WIDTH = 400;  // JFrame width
    public static final int HEIGHT = 420; // JFrame height   
   
    public Main() {
        //Sætter nogle options på JFrame
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //getContentPane().setLayout(new BorderLayout());
        setTitle("Talfinder");
        setBounds(X,Y,WIDTH,HEIGHT);
        try {
            UIManager.setLookAndFeel(
                UIManager.getSystemLookAndFeelClassName( ) );
        } catch (Exception e) { }
       
        //Sætter en button
        JButton knap = new JButton();
        knap.setText("Hent nye tal");
        knap.setBounds(20,20,100,100);
        knap.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                knapklik(evt);
            }
        });
       
        //Laver labels
        antaltal = new JLabel("");
        tal = new JLabel("");
        klikviser = new JLabel("");
       
        //Laver label og fylder den med data
        String streng3 = "version: 0.1";
        JLabel version = new JLabel(streng3);
        version.setLocation(20, 35);
        version.setAlignmentY(40);
        //JLabel klikviser = new JLabel(klik);
       
        //Sætter panelet og fylder det med strings
        JPanel topPanel = new JPanel();
        topPanel.setLayout(new GridLayout(5,1));
        getContentPane().add(topPanel);
        topPanel.add(knap);
        topPanel.add(antaltal);
        topPanel.add(tal);
        topPanel.add(klikviser);
        topPanel.add(version);
        //pack();
    }
   
    private void knapklik(java.awt.event.ActionEvent evt) {
        //Tilføjer tekst til labels
        String streng = "Arraylisten indeholder " + talfinder().size() + " udtrukne tal.";
        antaltal.setText(streng);
        String streng2 = "Udtrukne tal: " + talstreng(talfinder());
        tal.setText(streng2);
        klik++;
        String kliks = String.valueOf(klik);
        klikviser.setText(kliks);
        //pack();
    }
   
    public static void main(String[] args) {
        Main f = new Main();
        f.setVisible(true);
    }

    private static List talfinder() {
        // Talfinder (finder tal imellem 1 og 50)
        Random generator = new Random();
        List lst = new ArrayList();

        // Finder 5 tal mellem 1 og 50 og fyld det på arraylisten
        for (int i = 0; i < 5; i++) {
            int num1 = generator.nextInt(50) + 1;

            //smider det udtrukne tal "num1" i arraylisten
            lst.add(num1);
        }
        return lst;
    }
   
    private static String talstreng(List lst) {
        //skriver tal i arraylisten ud
        String indexnr = "";
        for (int i = 0; i < lst.size(); i++) {
            if(i > 0) indexnr += ", ";
            indexnr += lst.get(i);
        }
        return indexnr;
    }
}

Det kører udmærket, men jeg kan ikke får teksten i de enkelte "celler" at flytte sig. Og jeg kunne også godt tænke mit at lave knappen mindre (pt så fylder den hele "cellen" ud)..

mvh
Avatar billede arne_v Ekspert
26. december 2005 - 23:38 #9
Nu er jeg ikke GUI ekspert.

Høker løsningen er at lave grid layout på 5 x 3 og så bare putte tomme JLabel's i
den første og den tredie etc.

Det er selvfølgelig ikke den rigtige løsning.

Prøv at kigge på GridBagLayout.

Men nu begynder min viden at slippe op.
Avatar billede jaffafo Nybegynder
27. december 2005 - 00:12 #10
ok det prøver jeg så.. :)
Det er bare ret svært at finde det rette sted at læse ting når man ikke har en bog :/  Jeg googl'er bare hver gang jeg har et problem, men desværre så løser det ikke altid problemet.. men heldigvis har vi så eksperten :)

smider i et svar?
Avatar billede erikjacobsen Ekspert
27. december 2005 - 00:13 #11
Ingen point til mig, tak.
Avatar billede arne_v Ekspert
28. december 2005 - 23:14 #12
prøv evt. at stil et konkret spørgsmål hvor du beskriver hvordan tingene skal
se ud og se om ikke en af Swing hajerne kan komme op med den rigtige LayoutManager
til det

og et svar fra mig
Avatar billede jaffafo Nybegynder
29. december 2005 - 00:51 #13
arne_v:

Jeg har fået lidt hjælp fra en jeg kender (datamatiker) som har hjulpet mig meget.. en af tingene som jeg lærte af ham var at man godt kan add'e et JPanel til et andet JPanel, hvilket jo giver mig flere muligheder :) Hvertfald nok indtil videre.. ;)

Men igen..  tak for hjælpen :)
Avatar billede arne_v Ekspert
29. december 2005 - 01:06 #14
ah - det kunne jeg godt have fortalt dig

jeg tror at det er meget almindeligt med f.eks. JFrame content pane med
BorderLayout og 5 JPanels med andre layout managers (grid, flow etc.) på
disse

når man lærer at forstå de kære layout managers så kan man meget

og når nu du har lært hvordan det skal gøres så kan jeg med god samvittighed
vise dig hvordan det ikke skal laves:

package december;

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

public class Stupid extends JFrame implements ActionListener {
    public Stupid() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setLayout(null); // <----
        this.setSize(200, 200);
        JButton btn = new JButton("Test");
        btn.setSize(80, 20);
        btn.setLocation(60, 80);
        getContentPane().add(btn);
    }
    public void actionPerformed(ActionEvent e) {
    }
    public static void main(String[] args) {
        Stupid f = new Stupid();
        f.setVisible(true);
    }
}
Avatar billede erikjacobsen Ekspert
29. december 2005 - 12:20 #15
Og en null-layout manager, er een hvor man angiver x,y beliggenheden for hvert dims (setLocation).
Det lyder som en simpel og god løsning, men den har et problem, nemlig at Java er designet og beregnet til at kunne afvikles på mange platforme, hvor det ikke er sikkert de samme fonte findes, og hvor størrelser af diverse ting kan være anderledes (og mere end det). Derfor bøvler man med layout-managere.  ;)
Avatar billede arne_v Ekspert
29. december 2005 - 12:32 #16
der er også andre problemer med null layout:

hvis man skal indsætte en ekstra kontrol i en stor GUI så kan man
risikere at skulle rette i hundredevis af størrelser og placeringer

den slags er langt nemmere når layout manageren gør det for en
Avatar billede arne_v Ekspert
29. december 2005 - 13:05 #17
Og for dem som er utilfredse med standard layout managerne:
  http://java.sun.com/docs/books/tutorial/uiswing/layout/custom.html
Avatar billede jaffafo Nybegynder
29. december 2005 - 17:06 #18
måske i lige kan hjælpe med en ting.. ;)

Er det muligt at have luft imellem cellerne på en GridLayout? Jeg har søgt rundt, men har ikke findet noget. f.eks. jeg har en knap og en ComboBox lige ved siden af hinanden, og jeg ønsker ligt 5-10 px af luft imellem... :)
Avatar billede arne_v Ekspert
29. december 2005 - 17:20 #19
har du prøvet constructiren med 4 argumenter ?

GridLayout

public GridLayout(int rows,
                  int cols,
                  int hgap,
                  int vgap)

    Creates a grid layout with the specified number of rows and columns. All components in the layout are given equal size.

    In addition, the horizontal and vertical gaps are set to the specified values. Horizontal gaps are placed between each of the columns. Vertical gaps are placed between each of the rows.

    One, but not both, of rows and cols can be zero, which means that any number of objects can be placed in a row or in a column.

    All GridLayout constructors defer to this one.

    Parameters:
        rows - the rows, with the value zero meaning any number of rows
        cols - the columns, with the value zero meaning any number of columns
        hgap - the horizontal gap
        vgap - the vertical gap
    Throws:
        IllegalArgumentException - if the value of both rows and cols is set to zero
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