Kolejny prosty i edukacyjny programik napisany w Javie. Pojawiają się nowe komponenty w porównaniu do poprzedniej aplikacji. Plik główny:
package combo;
import javax.swing.*;
public class ComboTest {
public static void main(String[] args) {
ComboFrame frame = new ComboFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setVisible( true );
}
}
Jeśli nie wiadomo co się tu dzieje to zapraszam do lektury wcześniejszego wpisu.
Plik ComboFrame.java:
package combo;
import javax.swing.*;
import java.awt.*;
public class ComboFrame extends JFrame{
public ComboFrame()
{
setTitle( "Lista czcionek w JComboBox" );
setSize( WIDTH, HEIGHT );
ComboPanel panel = new ComboPanel();
Container cont = getContentPane();
cont.add( panel );
}
private static final int WIDTH = 200;
private static final int HEIGHT = 300;
}
Zbyt wiele się tu też nie dzieje więc jak coś niejasne to patrz poprzedni wpis.
Plik ComboPanel.java:
package combo;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import javax.swing.event.*;
public class ComboPanel extends JPanel{
public ComboPanel()
{
// initialization
labelSize = new Rectangle( 10, 10, 100, 20 );
comboSize = new Rectangle( 10, 60, 100, 20 );
sliderSize = new Rectangle( 10, 110, 100, 20 );
// get fonts
String[] fontNames = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
// set layout
setLayout( null );
// create components
combo = new JComboBox( fontNames );
label = new JLabel( "Napis testowy" );
slider = new JSlider( 4, 20, 12 );
label.setBounds( labelSize );
combo.setBounds( comboSize );
combo.addActionListener( new ComboHandler() );
slider.setBounds( sliderSize );
slider.addChangeListener( new SliderHandler() );
// add components to panel
add( label );
add( combo );
add( slider );
}
private class ComboHandler implements ActionListener
{
public void actionPerformed( ActionEvent event )
{
String font = (String)combo.getSelectedItem();
label.setFont( new Font( font, Font.PLAIN, slider.getValue() ) );
}
}
private class SliderHandler implements ChangeListener
{
public void stateChanged( ChangeEvent event )
{
label.setFont( new Font( (String)combo.getSelectedItem(), Font.PLAIN, slider.getValue() ) );
}
}
private Rectangle labelSize;
private Rectangle comboSize;
private Rectangle sliderSize;
private JComboBox combo;
private JLabel label;
private JSlider slider;
}
Ten plik wymaga już wyjaśnienia. Na początku inicjalizujemy obiekty typu Rectangle, za chwilę się okaże po co. Następnie korzystamy z dostępnej już nam wiedzy jak pobrać czcionki dostępne w systemie.
Teraz pierwsza ważna rzecz:
// set layout
setLayout( null );
REZYGNUJEMY z menedżera rozkładu komponentów. Oznacza to tylko, że trzeba wszystkie elementy pozycjonować ręcznie, podając koordynaty ich lewej górnej krawędzi ( zaznaczam, że oś pozioma “rośnie” w prawo, a pionowa w DÓŁ! ). I po to właśnie inicjalizowaliśmy wcześniej obiektu typu Rectangle – mogą one być argumentami funkcji setBounds() dla komponentów. A dokładniej to ustalamy współrzędne lewej górnej krawędzi, potem szerokość i na końcu wysokość ( stąd 4 argumenty ).
Tworzenie komponentów raczej nie jest niezwykłym kodem, wyjaśnienia wymagać mogą jedynie parametry konstruktora JSlider. Są to odpowiednio:
- wartość minimalna
- wartość maksymalna
- wartość domyślna
W dalszej części pojawia się nowy interface – ChangeListener. Implementjemy go, aby nasłuchiwać zdarzeń dla suwaka. ChangeListener posiada tylko jedną metodę do zaimplementowania i ma ona dokładnie takie samo działanie jak metoda actionPerformed() dla implementacji interface’u ActionListener. Celowo ten sam kod napisałem na dwa różne sposoby. Drugi sposób jest bardziej zwięzły i taki kod niektórym może wydawać się zagmatwany. W pierwszym przypadku dużo łatwiej jest odczytać i zrozumieć, co programista miał na myśli.