JScrollPane für JPanel einrichten


#1

Hey Community,
ich möchte ein Programm schreiben, in dem man ein Transportunternehmen leitet.
Nun möchte ich ein Shop-Fenster erstellen, in dem man sich kaufbaren Fahrzeuge anschauen kann.

Dafür habe ich folgenden Code geschrieben:

Code
[spoiler]

	private void createShopPanel() {

			final JScrollPane ShopScrollPane = new JScrollPane();
			ShopScrollPane.setLayout(null);
			ShopScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
			ShopScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
			ShopScrollPane.setBounds(0, 0, 1025, 650);

			ShopPanel = new JPanel();
			ShopPanel.setBounds(0, 0, 1300, 650);
			ShopPanel.setLayout(null);
			ShopPanel.setVisible(true);
			ShopPanel.add(ShopScrollPane);

			contentPane.add(ShopPanel);

			int fillheight = 0;

			// Add trucks

			ShopScrollPane.add(getShopSeperator("Trucks", fillheight));
			fillheight = fillheight + 40;

			ArrayList<Truck> TrucksInShop = manage.getTrucksInShop();
			if (TrucksInShop != null) {
				for (Truck x : TrucksInShop) {
					ShopScrollPane.add(getShopVehiclePanel(fillheight,
							x.getCapacity(), x.getName(), x.getRange(),
							x.getSpeed(), x.getWeight(), x.getType(),
							x.getSize(), x.getImagePath()));
					fillheight = fillheight + 122;
				}
			}

			// Add airplanes

			ShopScrollPane.add(getShopSeperator("Airplanes", fillheight));
			fillheight = fillheight + 40;

			ArrayList<Plane> PlanesInShop = manage.getPlanesInShop();
			if (PlanesInShop != null) {
				for (Plane x : PlanesInShop) {
					ShopScrollPane.add(getShopVehiclePanel(fillheight,
							x.getCapacity(), x.getName(), x.getRange(),
							x.getSpeed(), x.getWeight(), x.getType(),
							x.getSize(), x.getImagePath()));
					fillheight = fillheight + 122;
				}
			}

			// Add ship

			ShopScrollPane.add(getShopSeperator("Ships", fillheight));
			fillheight = fillheight + 40;

			ArrayList<Ship> ShipsInShop = manage.getShipsInShop();
			if (ShipsInShop != null) {
				for (Ship x : ShipsInShop) {
					ShopScrollPane.add(getShopVehiclePanel(fillheight,
							x.getCapacity(), x.getName(), x.getRange(),
							x.getSpeed(), x.getWeight(), x.getType(),
							x.getSize(), x.getImagePath()));
					fillheight = fillheight + 122;
				}
			}

	}

	private JPanel getShopSeperator(String Labeltext, int fillheight) {
		JPanel panel = new JPanel();
		panel.setBounds(5, fillheight + 10, 990, 30);
		panel.setBackground(Color.DARK_GRAY);
		panel.setLayout(null);

		JLabel label = new JLabel(Labeltext);
		label.setBounds(20, 0, 990, 30);
		label.setForeground(Color.WHITE);
		label.setFont(new Font("Tahoma", Font.BOLD, 14));
		label.setHorizontalAlignment(SwingConstants.CENTER);

		panel.add(label);

		return panel;
	}

	private JPanel getShopVehiclePanel(int fillheight, int capacity,
			String name, int range, int speed, int weight, int type, int size,
			String ImagePath) {

		JPanel panel = new JPanel();
		panel.setBorder(new LineBorder(new Color(0, 0, 0), 2));
		panel.setLayout(null);
		panel.setBackground(Color.LIGHT_GRAY);
		panel.setBounds(5, fillheight + 10, 990, 112);

		JLabel IconLabel = new JLabel("");
		IconLabel.setIcon(new ImageIcon(getClass().getResource(ImagePath)));
		IconLabel.setBounds(20, 13, 150, 54);
		panel.add(IconLabel);

		JLabel capacitylabel = new JLabel("CAPACITY:");
		capacitylabel.setBounds(180, 13, 140, 21);
		panel.add(capacitylabel);

		String x;

		if (type == 1) {
			x = "(Person)";
		} else {
			x = "(Cargo)";
		}

		JTextField txtfieldcapacity = new JTextField(capacity + x);
		txtfieldcapacity.setEditable(false);
		txtfieldcapacity.setBackground(Color.WHITE);
		txtfieldcapacity.setBounds(180, 43, 140, 21);
		panel.add(txtfieldcapacity);

		JLabel speedlabel = new JLabel("SPEED:");
		speedlabel.setBounds(340, 13, 140, 21);
		panel.add(speedlabel);

		JTextField txtfieldspeed = new JTextField(speed + "");
		txtfieldspeed.setEditable(false);
		txtfieldspeed.setBounds(340, 43, 140, 21);
		panel.add(txtfieldspeed);

		JTextField txtfieldrange = new JTextField(range + "");
		txtfieldrange.setEditable(false);
		txtfieldrange.setBackground(Color.WHITE);
		txtfieldrange.setBounds(500, 43, 140, 21);
		panel.add(txtfieldrange);

		JLabel rangelabel = new JLabel("RANGE:");
		rangelabel.setBounds(500, 13, 140, 21);
		panel.add(rangelabel);

		JLabel weightlabel = new JLabel("WEIGHT:");
		weightlabel.setBounds(660, 13, 140, 21);
		panel.add(weightlabel);

		JTextField txtfieldwight = new JTextField(weight + "");
		txtfieldwight.setEditable(false);
		txtfieldwight.setBackground(Color.WHITE);
		txtfieldwight.setBounds(660, 43, 140, 21);
		panel.add(txtfieldwight);

		JLabel sizelabel = new JLabel("SIZE:");
		sizelabel.setBounds(820, 13, 140, 21);
		panel.add(sizelabel);

		JTextField txtfieldsize = new JTextField(size + "");
		txtfieldsize.setEditable(false);
		txtfieldsize.setBackground(Color.WHITE);
		txtfieldsize.setBounds(820, 43, 140, 21);
		panel.add(txtfieldsize);

		JPanel buypanel = new JPanel();
		buypanel.setBackground(new Color(224, 255, 255));
		buypanel.setBounds(2, 80, 986, 30);
		buypanel.setLayout(null);
		panel.add(buypanel);

		JLabel pricelabel = new JLabel("Price: 10000");
		pricelabel.setBounds(750, 5, 87, 20);
		buypanel.add(pricelabel);
		pricelabel.setFont(new Font("Tahoma", Font.BOLD, 14));

		JLabel namelabel = new JLabel(name);
		namelabel.setBounds(20, 5, 87, 20);
		buypanel.add(namelabel);
		namelabel.setFont(new Font("Tahoma", Font.BOLD, 14));

		JButton button = new JButton("BUY");
		button.setBounds(910, 5, 60, 20);
		buypanel.add(button);

		return panel;
	}

[/spoiler]

Das sieht dann so aus:

Jetzt habe ich jedoch das Problem, dass ich es nicht hin bekomme, dass das ScrollPane dann auch scrollt.
Ich schätze der Fehler liegt darin, dass ich kein ViewPort festgelegt habe, aber wie mach ich das mit mehreren Panels?

MFG HaveANiceDay


#2

Werden denn Scrollbalken sichtbar, wenn du das Fenster verkleinerst?
Das Problem sehe ich vorrangig darin, dass deine JScrollPane keinen LayoutManager mehr hat. Sie kann also nicht berechnen, wann Scrollbalken zum Verschieben des Inhalts angezeigt werden müssen.
Denn die Berechnungen richten sich nach der bevorzugten Größe (Preferred) des Inhaltes.

[MENTION=1894]HaveANiceDay[/MENTION]: Ich habe mal noch ein Fragment mit LayoutManagern und einem fiktiven Model angehängt.

Den Quellcode findest du in der Jar-Datei.


#3

Moin,

[inline]ShopScrollPane.revalidate()[/inline] oder so was in der Art. Du musst am Ende der Scrollpane noch mitteilen das sich ihr Inhalt komplett geändert hat.


#4

Null Layout + Scrollpane = Aua. Entweder du lernst Layoutmanager oder benutzt mein DragLayout