Swing #2: Usuwanie narysowanych kształtów
Spis treści
Zadanie
Napisz aplikację wykorzystującą elementy AWT oraz Swing, która zawiera trzy przyciski:
- Pierwszy zmienia kolor tła panelu na losowy kolor: zielony, niebieski, lub czerwony.
- Drugi przycisk zmienia własne tło na dowolny kolor zdefiniowany przez ciebie. (Wykorzystaj metodę setBackground(Color) klasy JButton)
- Trzeci przycisk zmienia swoją etykietę na „Wciśnięty", po wciśnięciu. (Wykorzystaj metodę setText(String) klasy JButton)
Wszystkie elementy zdefiniuj w oddzielnych klasach (zewnętrznych) i skorzystaj z jednego z zarządców rozkładem.
Rozwiązanie
Postępując zgodnie ze wskazówkami zadanie nie powinno sprawiać problemów. Ponieważ w zadaniu jest powiedziane, że klasy mają być zdefiniowane oddzielnie, musimy przekazać pierwszemu przyciskowi referencję panelu, w którym będzie zmieniane tło.
Przycisk zmieniający tło panelu:
import java.awt.Color;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;
class FirstButton extends JButton implements ActionListener {
private JPanel buttonPanel;
private Color[] colors = { Color.GREEN, Color.BLUE, Color.RED };
FirstButton(JPanel buttonPanel) {
super("Pierwszy");
this.buttonPanel = buttonPanel;
addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
int index = new Random().nextInt(colors.length);
buttonPanel.setBackground(colors[index]);
}
}
Przycisk zmieniający własne tło:
import java.awt.Color;
import java.awt.event.*;
import javax.swing.*;
class SecondButton extends JButton implements ActionListener {
SecondButton() {
super("Drugi");
addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
setBackground(Color.YELLOW);
}
}
Przycisk zmieniający swoją etykietę:
import java.awt.event.*;
import javax.swing.*;
class ThirdButton extends JButton implements ActionListener {
private boolean wcisniety = false;
ThirdButton() {
super("Nie wciśnięty");
addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
if (wcisniety)
setText("Wciśnięty");
else
setText("Nie wciśnięty");
wcisniety = !wcisniety;
}
}
Panel:
import java.awt.*;
import javax.swing.JButton;
import javax.swing.JPanel;
public class ButtonPanel extends JPanel{
public static final int HEIGHT = 100;
public static final int WIDTH = 300;
private JButton greenButton;
private JButton blueButton;
private JButton redButton;
public ButtonPanel() {
greenButton = new FirstButton(this);
blueButton = new SecondButton();
redButton = new ThirdButton();
setLayout(new FlowLayout());
setPreferredSize(new Dimension(WIDTH, HEIGHT));
add(greenButton);
add(blueButton);
add(redButton);
}
}
Ramka:
import javax.swing.*;
public class ActionFrame extends JFrame {
public ActionFrame() {
super("Test akcji");
JPanel buttonPanel = new ButtonPanel();
add(buttonPanel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
}
Klasa testowa:
import java.awt.EventQueue;
class Test {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new ActionFrame();
}
});
}
}
Dyskusja i komentarze
Masz pytania do tego wpisu? Może chcesz się podzielić spostrzeżeniami? Zapraszamy dyskusji na naszej grupie na Facebooku.
Poniżej znajdziesz archiwalne wpisy z czasów, gdy strona była jeszcze hobbystycznym blogiem.
jacek
nie mogę tego zrozumieć, nie mogłem zrobić samemu, więc skopiowałem to wszystko, ale i tak mam ze 20 błędów
Arkadiusz
Jakie to błędy? Wklej jej i pamiętaj o znacznikach <code></code>
paulonio
Ja wykorzystałem to co było na lekcji i zmieniłem tylko w tym miejscu :) <code> if(source == kolorButton) setBackground(new Color( (int)(Math.random()*255),(int)(Math.random()*255),(int)(Math.random()*255) )); else if(source == blueButton) setBackground(Color.BLUE); else if(source == offButton) offButton.setText("Wciśnięty"); </code>
Mr_Fisq
Pytanie: Dlaczego linijka: <code> wcisniety = !wcisniety; </code> Występuje dopiero po instrukcji warunkowej, a nie przed? Takie rozwiązanie, iż napis na przycisku jest przeciwny do stanu składowej: <code> wcisniety </code>
KUX
Losowy kolor to metoda wewnątrz konstruktora domyslnego: public void losujKolor() { Color[] colors ={Color.YELLOW,Color.RED,Color.GREEN}; Color colorW = colors[new Random().nextInt(colors.length)]; setBackground(colorW); }
Robert
Nie doczytałem i moje guziki to klasy wewnętrzne. Mój pomysł na przycisk zmieniający losowo tło panelu: class Guzik1 extends JButton implements ActionListener { Guzik1() { super("Przycisk1"); addActionListener(this); } @Override public void actionPerformed(ActionEvent e) { Random losuj = new Random(); int a = losuj.nextInt(14); if (a>=0 && a=5 && a=10 && a<=14) { buttonpanel.setBackground(Color.RED); String b = Integer.toString(a); guzik1.setText("Wylosowano "+b+" wiec tlo czerwone."); } } } Najpierw losuje liczbę 0-14, przypisuję jej kolor, następnie rzutuję liczbę na String żeby wyświetlić ją na przycisku (bo setText() wyświetla tylko String). Pozdrawiam
Robert
Dlaczego w klasie ButtonPanel jest: greenButton = new FirstButton(this); chodzi mi konkretnie o 'this'; Pozdrawiam
Damian
"FirstButton(JPanel buttonPanel) { ... }" Oznacza to, że stworzony został konstruktor wymaga referencji do obiektu klasy JPanel, lub po niej dziedziczącej. Ta z kolei jest wymagana, żeby obiekt klasy "FirstButton" wiedział jakiego obiektu dotyczy jego zadanie, czyli zmiana tła panelu...
snt.banzai
należy jednakowoż zauważyć, iż pierwsze kliknięcie na trzeci przycisk nie powoduje zmiany wyświetlanego napisu. Ma to miejsce dopiero za drugim kliknięciem. A przynajmniej tak działa to u mnie.
Piotr
To chyba błąd. W każdym razie po zmianie "false" na "true" w lini "private boolean wcisniety = false;" w klasie "ThirdButton" zmienia się od pierwszego kliknięcia.
Leon
Moje losowanie kolorów wygląda następująco: Random r = new Random(); switch(r.nextInt(3)){ case 0: buttonPanel.setBackground(Color.GREEN); case 1: buttonPanel.setBackground(Color.red); case 2: buttonPanel.setBackground(Color.blue); } Dlaczego zawsze mi wyświetla tylko niebieski kolor?
void
A gdzie masz break? Jak nie ma break to leci po kolejnych "opcjach" i ostatecznie zostaje blue.
Bartol
Mam pytanie odnośnie tego pierwszego przycisku losujacego kolory. Za kazdym razem gry puszcze program i pierwszy przycisk jaki chce wcisną jest wlasnie tym przyciskiem losujacym kolor tla to wywal mi błąd w tej linijce: int index = new Random().nextInt(colors.length); ale jak najpierw klikne w ktorykolwiek inny przycisk i dopiero w ten to wszystko dziala pieknie, ktoświe dlaczego tak sie dzieje ?!