webForumDet fria alternativet

Springlayout krånglar...

8 svar · 339 visningar · startad av mo:d:fi

mo:d:fiMedlem sedan jan. 200474 inlägg
#1

Hej...

Sitter och bråkar fruktansvärt mycket med Springlayouten just nu för att få saker och ting att fungera för en gångs skull.

Har gjort en testklass med en springlayout som innhåller 6 JButtons.

En JFrame skapas enligt följande:

		JFrame fonster = new JFrame("inTouch");
		Container contentPane = fonster.getContentPane();
		lay = new SpringLayout();
		contentPane.setLayout(lay);

knapparna skappas och läggs till enligt följande:

		contentPane.add(forsta);

Sedan sätts alla placeringsförhållande upp så här:

		lay.putConstraint(SpringLayout.WEST, forsta, 5, SpringLayout.WEST, contentPane);
		lay.putConstraint(SpringLayout.NORTH, forsta, 5, SpringLayout.NORTH, contentPane);

		lay.putConstraint(SpringLayout.WEST, andra, 5, SpringLayout.WEST, contentPane);
		lay.putConstraint(SpringLayout.NORTH, andra, 5, SpringLayout.SOUTH, forsta);

		lay.putConstraint(SpringLayout.EAST, tredje, -5, SpringLayout.EAST, contentPane);
		lay.putConstraint(SpringLayout.NORTH, tredje, 5, SpringLayout.SOUTH, forsta);

		lay.putConstraint(SpringLayout.WEST, fjarde, 5, SpringLayout.WEST, contentPane);
		lay.putConstraint(SpringLayout.NORTH, fjarde, 5, SpringLayout.SOUTH, andra);

		lay.putConstraint(SpringLayout.WEST, femte, 5, SpringLayout.WEST, contentPane);
		lay.putConstraint(SpringLayout.NORTH, femte, 5, SpringLayout.SOUTH, fjarde);

		lay.putConstraint(SpringLayout.EAST, sjatte, -5, SpringLayout.EAST, contentPane);
		lay.putConstraint(SpringLayout.NORTH, sjatte, 5, SpringLayout.SOUTH, fjarde);

Sedan packas allting och skall köras enligt följande:

		fonster.pack();
		fonster.setVisible(true);
		fonster.setSize(new Dimension(270, 400));
		fonster.show();

Följande kod fungerar och allting är frid och fröjd men om jag tar bort setSize raden så kommer ingen JFrame upp när programmet körs. Det är alltså samma problem som jag brottas med som jag postade om i min förra tråd. Då kvarstod dock problemet med att ingen frame kommer upp även om jag lägger till setSize anropet.
Om nån lekt med Springlayout och kan ge lite tips och hjälp skulle det va super.

MVH Andreas

Aleph_OneMedlem sedan juni 2003370 inlägg
#2

Släng upp hela klassen så är det lättare att kolla igenom vad som inte är som det ska..

LimeMedlem sedan sep. 2001837 inlägg
#3

Jag tror att grejen är att du packar fönstret trots att alla komponenter ligger i lay. Testa att göra getContentPane().pack() istället...

/Lime

mo:d:fiMedlem sedan jan. 200474 inlägg
#4

getContentPane().pack()
och
fonster.getContentPane().pack()
(fonster är JFrame objektet)
ger båda kompileringsfel (cannot resolve symbol)

jmeMedlem sedan maj 20011 967 inlägg
#5

metoden pack() finns i klassen Window som ärvs därifrån av JFrame.

getContentPane() returnerar Container.

mo:d:fiMedlem sedan jan. 200474 inlägg
#6

man kan bli trött för mindre måste jag säga...
fått det att funka med knapparna, lösningen blev att sätta upp constraints för contentPane oxå enligt följande:

		lay.putConstraint(SpringLayout.EAST, contentPane, 5, SpringLayout.EAST, fjarde);
		lay.putConstraint(SpringLayout.SOUTH, contentPane, 5, SpringLayout.SOUTH, sjatte);

efter den implementeringen räcker det med frame.pack() & frame.setVisible(true); för att alling ska komma upp.
I min huvudklass dock fungerar ingenting fortfarande.
allting kompileras och körs men ingen frame kommer upp.
postar hela koden nu, ledsen men den e lite halv lång atm.


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import javax.swing.BorderFactory; 
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import javax.swing.border.EtchedBorder;

public class inTouch extends JFrame implements ActionListener {

		JButton kontaktButton;
		ImageIcon[] ikoner;		
		String[] status = {"Plugged In", "Absent minded", "Unconscious", "Unplugged", "Sign In"};
		Integer[] statusVektor;
		ImageIcon foto;
		JPopupMenu picPopup;
		JPopupMenu kontaktPopup;
		JMenuItem menuItem;
		ImageIcon[] foton;	
		String[] kontakter = {"Andie", "Erik", "Davie", "Mackan", "Richie"};
		Integer[] kontaktVektor;
		ListRenderer Listrenderare;
		JList kontaktLista;
		JScrollPane kontaktScroll;
		JButton ikonen;
		JLabel namn;
		JLabel sikon;
		JComboBox statusCombo;
		JButton picButton;
		JPanel panelen;
		JFrame framen;

		public static void main(String[] args) {
			inTouch fonster = new inTouch();
		}

		inTouch() {

		setTitle("inTouch v0.05alpha");
		Container contentPane = getContentPane();

		SpringLayout lay;

		lay = new SpringLayout();
		contentPane.setLayout(lay);

		init();

		lay.putConstraint(SpringLayout.WEST, ikonen, 5, SpringLayout.WEST, contentPane);
		lay.putConstraint(SpringLayout.NORTH, ikonen, 5, SpringLayout.NORTH, contentPane);

		lay.putConstraint(SpringLayout.WEST, namn, 5, SpringLayout.WEST, contentPane);
		lay.putConstraint(SpringLayout.NORTH, namn, 5, SpringLayout.SOUTH, ikonen);

		lay.putConstraint(SpringLayout.EAST, picButton, 5, SpringLayout.EAST, contentPane);
		lay.putConstraint(SpringLayout.NORTH, picButton, 5, SpringLayout.SOUTH, ikonen);

		lay.putConstraint(SpringLayout.WEST, kontaktScroll, 5, SpringLayout.WEST, contentPane);
		lay.putConstraint(SpringLayout.NORTH, kontaktScroll, 5, SpringLayout.SOUTH, namn);

		lay.putConstraint(SpringLayout.WEST, sikon, 5, SpringLayout.WEST, contentPane);
		lay.putConstraint(SpringLayout.NORTH, sikon, 5, SpringLayout.SOUTH,kontaktScroll);

		lay.putConstraint(SpringLayout.WEST, statusCombo, 5, SpringLayout.EAST, sikon);
		lay.putConstraint(SpringLayout.NORTH, statusCombo, 5, SpringLayout.SOUTH, kontaktScroll);

		lay.putConstraint(SpringLayout.EAST, contentPane, 5, SpringLayout.EAST, kontaktScroll);
		lay.putConstraint(SpringLayout.SOUTH, contentPane, 5, SpringLayout.SOUTH, statusCombo);

//		framen.getContentPane().add(panelen, BorderLayout.CENTER);

		setSize(new Dimension(270, 400));
		pack();
		setVisible(true);
//		framen.show();

		}

		private void init() {

		ikonen = new JButton("I");
		contentPane.add(ikonen);
		namn = new JLabel("Namn: Andie");
		contentPane.add(namn);

// S‰tt upp v‰lja kort knappen

		picPopup = new JPopupMenu();
		menuItem = new JMenuItem("Choose new picture...");		
		menuItem.addActionListener(this);
		picPopup.add(menuItem);
		foto = new ImageIcon();
		foto = createImageIcon("images/" + "myPic.jpg");
		picButton = new JButton("",foto);
		Insets m = new Insets(1,1,1,1);
		picButton.setMargin(m);
		MouseListener fotoListener = new Popup2Listener();
		picButton.addMouseListener(fotoListener);

		contentPane.add(picButton);

// Bygg upp kontaktlistan...
	
		kontaktVektor = new Integer[kontakter.length];
		foton = new ImageIcon[kontakter.length];
		for (int i=0; i < kontakter.length; i++) {
			kontaktVektor[i] = new Integer(i);
			foton[i] = createImageIcon("images/" + kontakter[i] + ".jpg");
		}		
		kontaktLista = new JList(kontaktVektor);
		kontaktLista.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
		kontaktLista.setLayoutOrientation(JList.HORIZONTAL_WRAP);
		kontaktLista.setVisibleRowCount(-1);
//		kontaktLista.setFixedCellHeight(20);
//		kontaktLista.setFixedCellWidth(220);
		kontaktScroll = new JScrollPane(kontaktLista);
		kontaktScroll.setPreferredSize(new Dimension(240, 80));
		kontaktScroll.setMinimumSize(new Dimension(240, 80));
		kontaktScroll.setMaximumSize(new Dimension(240, 80));
		kontaktScroll.setAlignmentX(LEFT_ALIGNMENT);
		Listrenderare = new ListRenderer();
		Listrenderare.setBorder(BorderFactory.createLineBorder(Color.black, 1));
		Listrenderare.setPreferredSize(new Dimension(240, 30));
		Listrenderare.setMinimumSize(new Dimension(240, 80));
		Listrenderare.setMaximumSize(new Dimension(240, 80));

		JButton kontaktButton = new JButton("kontaktKlick");
		kontaktButton.addActionListener(this);
		kontaktLista.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		kontaktLista.setLayoutOrientation(JList.VERTICAL);
		MouseListener kontaktListener = new Popup1Listener();
		kontaktLista.addMouseListener(kontaktListener);

		kontaktPopup = new JPopupMenu();
		menuItem = new JMenuItem("Send message");
		menuItem.addActionListener(this);
		kontaktPopup.add(menuItem);

		contentPane.add(kontaktScroll);	
		kontaktLista.setCellRenderer(Listrenderare);

		sikon = new JLabel("sI");
		contentPane.add(sikon);

// S‰tt upp v‰lja status ComboBoxen

		statusVektor = new Integer[status.length];
		ikoner = new ImageIcon[status.length];
		for (int i=0; i < status.length; i++) {
			statusVektor[i] = new Integer(i);
			ikoner[i] = createImageIcon("icons/" + status[i] + ".jpg");
		}

		statusCombo = new JComboBox(statusVektor);
		statusCombo.setSelectedIndex(0);
		statusCombo.addActionListener(this);

		contentPane.add(statusCombo);

	}

	public void actionPerformed(ActionEvent e) {
		if ("kontaktKlick".equals(e.getActionCommand())) {
			System.out.println("klick, klick");
		}
		else if ("Choose new picture...".equals(e.getActionCommand())) {
		}
		else if ("Send message".equals(e.getActionCommand())) {
		}
		else {
			JComboBox tmpCombo = (JComboBox)e.getSource();
			updateStatus(statusCombo.getSelectedIndex());
		}
	}

	private void updateStatus(int stat) {
	}

	// funktion fˆr h‰mtning av bild. Tack till sun!!!
	protected static ImageIcon createImageIcon(String path) {
		java.net.URL imgURL = inTouch.class.getResource(path);
		return new ImageIcon(imgURL);
	}
jmeMedlem sedan maj 20011 967 inlägg
#7

Några saker till att börja med. I java så finns det följande "regler":

- Klassnamnen börjar alltid med en stor bokstav
- variabelnamn börjar aldrig med en stor bokstav (om det inte är en varoiabel vars värde aldrig ändras, fast då skrivs hela variabeln med stora bokstäver).
- medlems-variablar deklararerar man vanligtvis som privata(nyckelordet 'private') och sedan skapar publika(nyckelorder 'public')setXXX()- och getXXX()-metoder som man kan komma åt dessa medlemsvariablar.
- man brukar deklarera kontruktörer som publika. Har du ingen så kommer enbart de klasser som finns i samma paket att kunna skapa instanser av denna klass. Har du private, kan ingen utom klassen själv skapa instanser av den. Det finns tillfällen då man vill ha alla konstruktörer privata, t ex då man endast vill ha en instans av klassen åt gången -> Singletons.

Jag får inte din kod att kompileras:

Följande rader är lite konstiga och jag tror du har tänkt lite fel:

MouseListener kontaktListener = new Popup1Listener();
MouseListener fotoListener = new Popup2Listener();

Varför skapar du två olika lyssnare?

Du bör nog kunna klara dig med endast en lyssnare som sedan i implementerade metoden tittar på vilket objekt som har fokus.

Du har inte publicerat koden för dina lyssnar-klasser.

Sedan så har du i init() metoden variabeln contentPane, men den hittas inte för du har skapat den inuti konstruktören och då syns den endast i konstruktören.

Skapa den som en medlemsvariabel istället. Då blir den synlig för alla metoder i din klass.

mo:d:fiMedlem sedan jan. 200474 inlägg
#8

gjorde contentPane global så att den kan nås av alla funktioner.
contentPane = getContentPane(); skapar sedan variablen innan init() anropas. desvärre blev slutresultatet detsamma, ingenting kommer upp =(

Skapade 2 lyssnarklasser från början för att hålla isär dem utan att krångla till allting. ville först bara skapa ett fungerande skal som jag kan bygga ut enkelt med alla funktioner och modifierade renderare sedan.
Angående alla "osynliga" java regler som man egentligen ska följa så måste jag erkänna att jag personligen aldrig följer dem. förmodligen för att jag alltid har så små egna projekt där koden aldrig ser omvärldens dagsljus och jag är den enda som behöver följa den, antar att jag får försöka bättra mig i framtiden när jag ska posta här ;)

	class Popup1Listener extends MouseAdapter {
		public void mousePressed(MouseEvent e) {
			if (e.getClickCount() == 2) {
				kontaktButton.doClick();			 //emulera knapp klick
			}
			else if (!e.isPopupTrigger()) {
				kontaktPopup.show(e.getComponent(), e.getX(), e.getY());
			}
		}
	}
	class Popup2Listener extends MouseAdapter {
		public void MousePressed(MouseEvent e) {
			if (!e.isPopupTrigger()) {
				picPopup.show(e.getComponent(), e.getX(), e.getY());
			}
		}
	}

// ListRenderer ‰r den klass som renderar list objekten.
// Klassen utgÂr frÂn en JPanel och implementerar ListCEllRenderer som ‰r den defaulta renderaren.
// JPanelen innehÂller bla ImageIcon's och JLabels med borders fˆr att fixa grafiken
// 
// I slutgiltig version skall Panelen byggas upp av inTouch Ikon, Namn och Foto, samt en "ram"

	class ListRenderer extends JLabel implements ListCellRenderer {
		public ListRenderer() {
			setOpaque(true);
		}
		public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {

			int selectedIndex = ((Integer)value).intValue();
			if (isSelected) {
				setBackground(list.getSelectionBackground());
				setForeground(list.getSelectionForeground());
			} else {
				setBackground(list.getBackground());
				setForeground(list.getForeground());
			}
	
			ImageIcon icon = foton[selectedIndex];
			setText(kontakter[selectedIndex]);
			setIcon(icon);
	
			return this;
		}
	}
}
mo:d:fiMedlem sedan jan. 200474 inlägg
#9

jag skäms och känner mig fruktansvärt konfunderad.
hade försökt skriva om listrenderaren till att bygga på JPanel istället som den skall göra i framtiden men ändrade tillbaka till JLabel, kompilerade och oj då, helt plötsligt fungerar allting.
slutsatsen som man kan dra är väl att de 2 sista putConstraint anropen är vitala, konstigt är dock att sun's exempel fungerar utan dessa 2 anrop...

tack för hjälpen och om nån har erfarenhet av att bygga egen listrenderar klass som bygger på JPanel e det bara att höra av sig.

/ Andreas

Genererad på 381 ms · cache AV · v20260730165559-full.f96bc7eb