Man skapar en instans av JTabbedPane, och lägger till flikar med metoden addTab.
Programmet JTabbedDemo.java:
// Efter Skansholm: Java direkt med Swing import java.awt.*; import javax.swing.*; public class JTabbedDemo extends JFrame { private JButton b1 = new JButton("1"); private JButton b2 = new JButton("2"); private JButton b3 = new JButton("3"); private JButton b4 = new JButton("4"); private JTextArea a = new JTextArea("En arbetsyta"); private JLabel bl = new JLabel(new ImageIcon("blommor.jpg")); public JTabbedDemo() { super("JTabbedDemo"); Container cp = getContentPane(); JTabbedPane tp = new JTabbedPane(); cp.add(tp); // Kort 1 JPanel kort1 = new JPanel(); tp.addTab("Spel", kort1); kort1.setLayout(new GridLayout(2, 2)); kort1.add(b1); kort1.add(b2); kort1.add(b3); kort1.add(b4); // Kort 2 JScrollPane kort2 = new JScrollPane(a); tp.addTab("Arbete", new ImageIcon("hammer.gif"), kort2); // Kort 3 JScrollPane kort3 = new JScrollPane(bl); tp.addTab("Blomma", null, kort3, "Visar påskliljor"); setSize(225, 250); setVisible(true); setDefaultCloseOperation(EXIT_ON_CLOSE); } public static void main (String[] arg) { JTabbedDemo j = new JTabbedDemo(); } }
Jämför med JButton och gränssnittet ActionListener:
Programmet Musexempel1.java:
// Musexempel1.java import javax.swing.*; import java.awt.*; import java.awt.event.*; import javax.swing.border.*; class Muspanel extends JPanel { public Muspanel() { super(new FlowLayout()); JPanel dumpanel1 = new JPanel(); dumpanel1.setBackground(new Color(0.98f, 0.97f, 0.85f)); Dimension size = new Dimension(100, 100); dumpanel1.setPreferredSize(size); dumpanel1.setMinimumSize(size); dumpanel1.setBorder(new LineBorder(Color.red, 2)); add(dumpanel1); BlankArea dumpanel2 = new BlankArea(); add(dumpanel2); JTextArea textarea = new JTextArea(); textarea.setEditable(false); JScrollPane scrollPane = new JScrollPane(textarea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); scrollPane.setPreferredSize(new Dimension(300, 75)); add(scrollPane); Muslyssnare lyssnare = new Muslyssnare(textarea); dumpanel1.addMouseMotionListener(lyssnare); dumpanel2.addMouseMotionListener(lyssnare); setPreferredSize(new Dimension(400, 200)); } // Muspanel private class Muslyssnare implements MouseMotionListener { private JTextArea textarea; public Muslyssnare(JTextArea textarea) { this.textarea = textarea; } public void mouseMoved(MouseEvent e) { log("Flyttning", e); } public void mouseDragged(MouseEvent e) { log("Dragning", e); } private void log(String eventDescription, MouseEvent e) { textarea.append(eventDescription + " (" + e.getX() + "," + e.getY() + ")" + " på " + e.getComponent().getClass().getName() + "\n"); textarea.setCaretPosition(textarea.getDocument().getLength()); } } // class Muslyssnare } // class Muspanel class Musfönster extends JFrame { public Musfönster() { super("Musfönster"); getContentPane().add(new Muspanel()); pack(); } } // class Musfönster public class Musexempel1 { public static void main(String[] args) { Musfönster m = new Musfönster(); m.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); m.setVisible(true); } } // class Musexempel1
Man kan skapa en blank area för musen att röra sig över genom ett antal anrop, eller så kan man tänka objektorienterat och göra en klass som representerar en sån area. Klassen BlankArea, som finns i filen BlankArea.java:
import javax.swing.JPanel; import java.awt.Dimension; import java.awt.Color; import javax.swing.border.LineBorder; public class BlankArea extends JPanel { final Dimension mySize = new Dimension(100, 100); public BlankArea() { setBackground(new Color(0.98f, 0.97f, 0.85f)); setBorder(new LineBorder(Color.green, 2)); } public Dimension getPreferredSize() { return mySize; } public Dimension getMinimumSize() { return mySize; } } // class BlankArea
För musklick har vi gränssnittet MouseListener:
Ur programmet Musexempel2.java:
Mer ur programmet Musexempel2.java:Muslyssnare lyssnare = new Muslyssnare(textarea); dumpanel1.addMouseListener(lyssnare); dumpanel2.addMouseListener(lyssnare);
private class Muslyssnare implements MouseListener { private JTextArea textarea; public Muslyssnare(JTextArea textarea) { this.textarea = textarea; } public void mousePressed(MouseEvent e) { log("Musen nertryckt; antal klick = " + e.getClickCount(), e); } public void mouseReleased(MouseEvent e) { log("Musen släppt; antal klick = " + + e.getClickCount(), e); } public void mouseEntered(MouseEvent e) { log("Musen kom in", e); } public void mouseExited(MouseEvent e) { log("Musen lämnade", e); } public void mouseClicked(MouseEvent e) { log("Musklick; antal klick = " + e.getClickCount() + ")", e); } private void log(String eventDescription, MouseEvent e) { textarea.append(eventDescription + " (" + e.getX() + "," + e.getY() + ")" + " på " + e.getComponent().getClass().getName() + "\n"); textarea.setCaretPosition(textarea.getDocument().getLength()); } } // class Muslyssnare
Därför finns en adapterklass som heter MouseAdapter.
Den har alla metoderna i gränssnittet, men de är tomma och gör inget:
Ur programmet Musexempel3.java:public void mousePressed(MouseEvent e) { }
private class Muslyssnare extends MouseAdapter implements MouseListener { private JTextArea textarea; public Muslyssnare(JTextArea textarea) { this.textarea = textarea; } public void mouseClicked(MouseEvent e) { log("Musklick; antal klick = " + e.getClickCount() + ")", e); } private void log(String eventDescription, MouseEvent e) { textarea.append(eventDescription + " (" + e.getX() + "," + e.getY() + ")" + " på " + e.getComponent().getClass().getName() + "\n"); textarea.setCaretPosition(textarea.getDocument().getLength()); } } // class Muslyssnare
Thread programming can be tricky. Whenever possible, you should use high-level thread API such as the java.util.Timer class introduced in version 1.3 of the Java platform. Timer and its companion class, TimerTask, are useful when your program must perform a task repeatedly or after a delay.
Kom ihåg klassen Presenter.java från föreläsning 4.
Man kan göra samma sak med en timer, i stället för att skapa egna trådar. Klassen PresenterTask.java:
Men tänk på att en java.util.Timer internt har sin egen tråd:import java.util.Timer; import java.util.TimerTask; public class PresenterTask extends TimerTask { private String message; private double sleepTime; private int steps; public PresenterTask(String message, double sleepTime) { this.message = message; this.sleepTime = sleepTime; this.steps = 0; Timer timer = new Timer(); timer.schedule(this, 0, (int)(sleepTime * 1000)); } public void run() { for (int i = 0; i < this.steps; ++i) System.out.print(" "); ++this.steps; System.out.println(this.message); } // run public static void main(String[] args) { PresenterTask t1 = new PresenterTask("Turbo", 0.1); PresenterTask t2 = new PresenterTask("Svensson", 0.2); PresenterTask t3 = new PresenterTask("Skalman", 0.3); } // main } // class PresenterTask
Man kan också ange en tidpunkt. Exempel från Sun:
En timer kan tas bort med metoden cancel.//Get the Date corresponding to 11:01:00 pm today. Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, 23); calendar.set(Calendar.MINUTE, 1); calendar.set(Calendar.SECOND, 0); Date time = calendar.getTime(); timer = new Timer(); timer.schedule(new RemindTask(), time);
Till skillnad från java.util.Timer så har javax.swing.Timer en enda tråd för alla timers (de samlas i en kö) så man kan ha många javax.swing.Timer utan att det gör något.
Exempel på användning: tooltips.
Tips om läsning hos Sun:
(Jaja, bilden står still. Men prova den här i stället.)
Programmet Grafikdemo6.java:
import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.border.*; class Cirkeldiagram extends JPanel { private int värde; private int max; public Cirkeldiagram(int värde, int max) { if (max <= 0) throw new IllegalArgumentException("max = " + max + ", ska vara > 0"); if (värde < 0 || värde > max) throw new IllegalArgumentException("värde = " + värde + ", ska vara 0.." + max); this.värde = värde; this.max = max; setBackground(Color.white); } public Cirkeldiagram(int värde) { this(värde, 100); } public Cirkeldiagram() { this(0, 100); } public void setVärde(int värde) { if (värde < 0 || värde > max) throw new IllegalArgumentException("värde = " + värde + ", ska vara 0.." + max); this.värde = värde; repaint(); } public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.blue); Insets i = getInsets(); int bredd = getWidth() - i.left - i.right; int höjd = getHeight() - i.top - i.bottom; int diameter = Math.min(bredd, höjd); int x = i.left + (bredd - diameter) / 2; int y = i.top + (höjd - diameter) / 2; g.drawOval(x, y, diameter, diameter); double andel = (double)värde / max; int vinkelandel = (int)(andel * 360 + 0.5); g.fillArc(x, y, diameter, diameter, 90, -vinkelandel); } } // class Cirkeldiagram class Grafikfönster extends JFrame { private Cirkeldiagram cd = new Cirkeldiagram(0, 100); JSlider s = new JSlider(0, 100, 0); public Grafikfönster(String titel) { super(titel); Container cp = getContentPane(); cp.add(cd); } public Cirkeldiagram cirkeldiagram() { return cd; } } // class Grafikfönster class Animeringstråd extends Thread { Cirkeldiagram cirkeldiagram; int värde = 0; public Animeringstråd(Cirkeldiagram cd) { this.cirkeldiagram = cd; start(); } public void run() { while (true) { ++värde; if (värde == 100) värde = 0; // cirkeldiagram.setVärde(värde); SwingUtilities.invokeLater(new Runnable() { public void run() { cirkeldiagram.setVärde(värde); } }); try { Thread.sleep(100); } catch (InterruptedException e) { System.out.println("Oj! Sömnen avbruten!"); } } } } // class Animeringstråd public class Grafikdemo6 { public static void main(String[] args) { Grafikfönster g = new Grafikfönster("Grafikdemo6"); g.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); g.setSize(300, 300); g.setVisible(true); Animeringstråd t = new Animeringstråd(g.cirkeldiagram()); } // main } // class Grafikdemo6
class TimerHandler implements ActionListener { private Cirkeldiagram cirkeldiagram; private int värde = 0; public TimerHandler(Cirkeldiagram cd) { cirkeldiagram = cd; } public void actionPerformed(ActionEvent e) { ++värde; if (värde == 100) värde = 0; cirkeldiagram.setVärde(värde); } // run } // class TimerHandler public class Grafikdemo7 { public static void main(String[] args) { Grafikfönster g = new Grafikfönster("Grafikdemo7"); g.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); g.setSize(300, 300); g.setVisible(true); TimerHandler th = new TimerHandler(g.cirkeldiagram()); javax.swing.Timer timer = new javax.swing.Timer(100, th); timer.start(); } // main } // class Grafikdemo7
På java.sun.com finns, förutom API:specen och andra manualer, också en stor mängd tutorials ("handledningar" på svenska), med kodexempel.
Här är några tutorials och artiklar om Swing: