Avatar billede tri Nybegynder
25. november 2002 - 16:35 Der er 10 kommentarer og
1 løsning

Swing: setBounds?

Jeg har en frame med size 500 * 500

Hvis man bruger setBounds() på sine swing componenter, og resizer Framen så den bliver mindre, så kan man ikke se sine componenter mere.

Er det muligt at bruge setBounds i kombination med en bestemt layout, så ens komponenter automatisk følger framens størrelse?


Jeg er godt klar over at det kan lade sig gøre, hvis man ikke bruger setBounds, og kun bruger en layoutManager.

Men jeg ville lige høre om det kan lade sig gøre ved brug at setBounds?
Avatar billede carstenknudsen Nybegynder
25. november 2002 - 17:05 #1
Det kan du meget besværligt gøre ved at
lave en listener der lytter til når
framen bliver resizet, men så skal du
beregne den nye størrelse af samtlige komponenter,
og sætte dem eksplicit med setBounds.
Som du selv skriver er det dog bedst at bruge
en fornuftig layout manager, da den laver
alle disse beregninger selv.
Avatar billede tri Nybegynder
26. november 2002 - 09:14 #2
carsten:

Jeg har nu lavet en metode som beregner den nye heigth og width når man har resized framen.
Men hvordan får jeg så placeret min knap på den nye position?
Helst på en smart måde, uden brug af private variabler!


Her er mit mini eksempel med en knap:


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

public class TestSwing extends JFrame implements ActionListener, ComponentListener {
    private JFrame window = new JFrame();
    private int aktuelWidth = 0;
    private int aktuelHeigth = 0;
    private JPanel panel = new JPanel();


    public TestSwing() {

        window.addComponentListener(this);

        window.setSize(300, 300);
        window.setBackground(Color.gray);

        panel.setLayout(null);
        createButtons();

        window.getContentPane().add(panel, BorderLayout.CENTER);
        window.setVisible(true);

        Rectangle frameDim = window.getBounds();
        aktuelWidth = frameDim.width;
        aktuelHeigth = frameDim.height;
    }


    public void createButtons() {
        JButton TestKnap = new JButton("Test");
        TestKnap.setBounds(15, 15, 80, 20);
        panel.add(TestKnap);
    }


    //tjekker for ændringer i JFramen!
    public void componentResized(ComponentEvent w) {
        Rectangle frameDim = window.getBounds();

        //de nye størrelser
        int newWidth = frameDim.width;
        int newHeigth = frameDim.height;

        //beregner ændringer i width og heigth på framen
        int beregnetWidth = newWidth - aktuelWidth;
        int beregnetHeigth = newHeigth - aktuelHeigth;

        //sætter de nye værdier som aktueller værdier
        aktuelWidth = aktuelWidth + beregnetWidth;
        aktuelHeigth = aktuelHeigth + beregnetHeigth;

        System.out.println("beregnetWidth: " + beregnetWidth);
        System.out.println("beregnetHeigth: " + beregnetHeigth);

    }

    public void componentMoved(ComponentEvent w) {
    }

    public void componentHidden(ComponentEvent w) {
    }

    public void componentShown(ComponentEvent w) {
    }

    public void actionPerformed(ActionEvent e) {
    }


    public static void main(String[] args) {
        TestSwing test = new TestSwing();

    }

}
Avatar billede carstenknudsen Nybegynder
26. november 2002 - 10:07 #3
Du skal erklære TestKnap som en private variable, ellers kan
du ikke få fat i den og sætte dens bounds.
Dernæst skal du tilføje følgende kode som det
sidste i componentResized. Bemærk at koden ikke
tager hensyn til insets, dvs rammernes bredde og højde.
For at få en perfekt centrering mht disse skal du
også have fat i insets og korrigere.
    try{
        Dimension d = TestKnap.getSize();
        int W = d.width;
        int H = d.height;
        TestKnap.setBounds(aktuelWidth/2-W/2,aktuelHeigth/2-H/2,W,H);
    }
    catch(NullPointerException npe) {}
Avatar billede tri Nybegynder
26. november 2002 - 10:32 #4
Hej igen, og tak.

Jeg synes at der er noget galt med denne linje:
TestKnap.setBounds(aktuelWidth/2-W/2,aktuelHeigth/2-H/2,W,H);
Første gang man resizer framen, så bliver knappen centreret!!
Det er jo ikke meningen.
Men efterfølgende når man resizer, så virker det.


Jeg har desuden fået fat i Insets.
Men hvordan sætter jeg dem efter resize?





koden:

package swing;

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

public class TestSwing extends JFrame implements ActionListener, ComponentListener {
    private JFrame window = new JFrame();
    private int aktuelWidth = 0;
    private int aktuelHeigth = 0;
    int insetsLeft = 0;
    int insetsRigth = 0;
    int insetsTop = 0;
    int insetsButtom = 0;
    private JPanel panel = new JPanel();
    JButton TestKnap = new JButton("Test");


    public TestSwing() {

        window.addComponentListener(this);

        window.setSize(300, 300);
        window.setBackground(Color.gray);

        panel.setLayout(null);
        createButtons();

        window.getContentPane().add(panel, BorderLayout.CENTER);
        window.setVisible(true);

        Rectangle frameDim = window.getBounds();
        aktuelWidth = frameDim.width;
        aktuelHeigth = frameDim.height;

        Insets insets = window.getInsets();
        insetsLeft = insets.left;
        insetsRigth = insets.right;
        insetsTop = insets.top;
        insetsButtom = insets.bottom;
    }


    public void createButtons() {
        TestKnap = new JButton("Test");
        TestKnap.setBounds(15, 15, 80, 20);
        panel.add(TestKnap);
    }


    //tjekker for ændringer i JFramen!
    public void componentResized(ComponentEvent w) {
        Rectangle frameDim = window.getBounds();

        //de nye størrelser
        int newWidth = frameDim.width;
        int newHeigth = frameDim.height;

        Insets insets = window.getInsets();
        insetsLeft = insets.left;
        insetsRigth = insets.right;
        insetsTop = insets.top;
        insetsButtom = insets.bottom;

        //beregner ændringer i width og heigth på framen
        int beregnetWidth = newWidth - aktuelWidth;
        int beregnetHeigth = newHeigth - aktuelHeigth;

        //sætter de nye værdier som aktueller værdier
        aktuelWidth = aktuelWidth + beregnetWidth;
        aktuelHeigth = aktuelHeigth + beregnetHeigth;


        System.out.println("beregnetWidth: " + beregnetWidth);
        System.out.println("beregnetHeigth: " + beregnetHeigth);

        try {
            Dimension d = TestKnap.getSize();
            int W = d.width;
            int H = d.height;
            TestKnap.setBounds(aktuelWidth / 2 - W / 2, aktuelHeigth / 2 - H / 2, W, H);


        }
        catch (NullPointerException npe) {
        }

    }

    public void componentMoved(ComponentEvent w) {
    }

    public void componentHidden(ComponentEvent w) {
    }

    public void componentShown(ComponentEvent w) {
    }

    public void actionPerformed(ActionEvent e) {
    }


    public static void main(String[] args) {
        TestSwing test = new TestSwing();

    }

}
Avatar billede carstenknudsen Nybegynder
26. november 2002 - 10:52 #5
Så ved jeg ikke hvad du er ude efter. Du vil have at man skal
kunne se komponenten når man resizer. Det kan man da den placeres
lige i centrum. Hvor vil du ellers have den? Du kan altid
sætte setBounds(0,0,w,h) så ses den i øverste venstre hjørne.
Hvis du præciserer hvad du ønsker kan det være jeg kan hjælpe,
men den er da synlig nu :)
Avatar billede tri Nybegynder
26. november 2002 - 11:03 #6
ok, jeg prøver lige igen :-)

Jeg har en frame som er 300*300

Først sætter jeg min knap på et præcis punkt:
TestKnap.setBounds(60, 15, 80, 20);


Herefter resizer jeg min frame, så den bliver 310*300
Altså 10 større i width'en.
Nu ønsker jeg også at min knap skal flyttes 10 i width'en
Avatar billede carstenknudsen Nybegynder
26. november 2002 - 11:16 #7
I den try-catch der er kan du så istedet
hente bounds fra komponenten og addere
dine beregnetW/H til bounds, og kalde
setBounds igen: setBounds(oldXBound+beregnetWidth,oldYBound+beregnetHeight,80,20)
Avatar billede tri Nybegynder
27. november 2002 - 09:12 #8
ok. nu virker det.

Men jeg må nok erkende at det er rimelig besværligt, hvis man har mange komponenter. Så er det nok lettere at kende de forskellige LayoutManager's godt.

Er der nogle standard LayoutManagers man skal bruge, hvis man ønsker at man kan resize sit window, og bagefter stadig kan se alle komponenterne?
(så komponenterne bare tilpasser sig i størrelsen.)

(Ligesom IntelliJ editoren el. Eclipse editoren gør).


Iøvrig tak for hjælpen.
Avatar billede carstenknudsen Nybegynder
27. november 2002 - 10:26 #9
Ja, du har fuldkommen ret i at man skal kende de
medfølgende layout managere. Hvis du bruger et
eller andet IDE så pas på med at bruge en
af deres managere, det har andre ikke tilrådighed,
og din kode kan ikke bruges andre steder.
De fleste layout manager vil vise dig alle komponenter
med mindre du gør dit vindue meget lille. Selv
FlowLayout der er det simpleste vil kunne det.
Af de mest brugbare vil jeg nævne BorderLayout hvor
du kan bestemme om en komponent skal være i
nord,syd,øst,vest eller centrum. Det lyder som
om det er meget få men husk at de enkelt komponenter
jo typisk vil indeholde andre managere, f.eks. til
at samle et antal knapper under eller ved siden af
hinanden. Her bruger man ofte et JPanel til at holde disse.
En anden meget brugbar komponent i den sammenhæng er
Box'e, hvor du kan kalde Box.createVerticalBox og
tilsvarende Box.createHorizontalBox. Til dem kan
du bare add'e komponenter, og boxene har den
egenskab at de sørger for at komponenterne får
samme størrelse, f.eks. med en horisontal box
får alle komponenter samme højde, og modsat med
en vertikal box. Husk at du kun skal proppe
de elementer ind der i forvejen har nogenlunde
samme størrelse. Så, kort sagt, lær BorderLayuot
og Box klassen at kende.
Layout er, som du har set, et ret komplekst område
hvis man selv vil lave noget. Hvis du laver
komplekse layouts med de indbyggede managere skal
du være klar over at de fleste swing komponenter
har en minimal størrelse, en maksimal størrelse,
og en foretrukken størrelse, og hvis du designer
komponenter skal du sørge for at dine komponenter
også har det. God fornøjelse.
Avatar billede tri Nybegynder
27. november 2002 - 15:05 #10
takker for den gode forklaring.
Avatar billede tri Nybegynder
04. december 2002 - 11:33 #11
carsten:

Når du har 5 min. kan jeg så få dig til at kigge på http://www.eksperten.dk/spm/290790 ?
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