PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [JAVA] JSlider mit Focus, leider ohne Hervorhebung


Pinoccio
2010-01-28, 18:44:51
Hallo,

einige zur Interaktion gedachten Oberflächenelemente in JAVA, wie z.B. (J)Buttons, sind bei Auswahl über die Tastatur hervorgehoben, wenn sie gerade den Focus haben.
Nun verwende ich auch JSlider. Bislang habe ich leider keine (elegante*) Möglichkeit gefunden auch bei diesen ein solches Verhalten zu bekommen.

Mein Beispiel
Der JButton links hat den Focus, erkennbar an der Umrahmung des Textes. Er könnte nun bspw. per Leertaste gedürckt werden.
http://www.abload.de/img/sl54tt.gif (http://www.abload.de/image.php?img=sl54tt.gif)

Der obere JSlider hat den Focus. Per Pfeiltasten ist er nun bedienbar. Leider ist dies aber nicht erkennbar, insbesondere sieht man (ohne es auszuprobieren) nicht, ob und ggfs. welcher JSlider aktiv ist.
http://www.abload.de/img/sl2536i.gif (http://www.abload.de/image.php?img=sl2536i.gif)

Was kann ich da tun?

Sollte out-of-the-Box laufen.
import java.awt.FlowLayout;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.Hashtable;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;


public class TestingSliders extends JFrame implements ChangeListener,
WindowListener {

JLabel value1;
JLabel value2;
JSlider sl1;
JSlider sl2;
JButton b1;
JButton b2;


public static void main(String[] argv) {

TestingSliders ts = new TestingSliders();
ts.inti();
ts.setSize(300, 300);
ts.setVisible(true);
ts.addWindowListener(ts);
}

public void inti() {



sl1 = new JSlider(JSlider.HORIZONTAL, 0, 10, 5);
sl2 = new JSlider(JSlider.HORIZONTAL, 0, 10, 5);

sl1.addChangeListener(this);
sl2.addChangeListener(this);

sl1.setMajorTickSpacing(10);
sl1.setMinorTickSpacing(1);
sl1.setPaintTicks(true);
sl1.setPaintLabels(true);

sl2.setMajorTickSpacing(10);
sl2.setMinorTickSpacing(1);
sl2.setPaintTicks(true);
sl2.setPaintLabels(true);

value1 = new JLabel("Value 1: 5");
value2 = new JLabel("Value 2: 5");


Hashtable<Integer,JLabel> labelTable1 = new Hashtable<Integer,JLabel>();
labelTable1.put(new Integer(0), new JLabel(""+0));
labelTable1.put(new Integer(5), value1);
labelTable1.put(new Integer(10), new JLabel(""+10));
sl1.setLabelTable(labelTable1);

Hashtable<Integer,JLabel> labelTable2 = new Hashtable<Integer,JLabel>();
labelTable2.put(new Integer(0), new JLabel(""+0));
labelTable2.put(new Integer(5), value2);
labelTable2.put(new Integer(10), new JLabel(""+10));
sl2.setLabelTable(labelTable2);

sl1.setPaintLabels(true);
sl2.setPaintLabels(true);

b1 = new JButton("Out of work - but selectable");
b2 = new JButton("dito");

this.setLayout(new FlowLayout());
this.add(sl1);
this.add(sl2);
this.add(b1);
this.add(b2);

}

public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider) e.getSource();
if (!source.getValueIsAdjusting()) {
if (source.equals(sl1)) {
value1.setText("Value 1: " + source.getValue());
}
if (source.equals(sl2)) {
value2.setText("Value 2: " + source.getValue());
}
}

}

public void windowActivated(WindowEvent arg0) { }

public void windowClosed(WindowEvent arg0) {
this.dispose();
System.exit(0);
}

public void windowClosing(WindowEvent arg0) {
this.dispose();
System.exit(0);
}

public void windowDeactivated(WindowEvent arg0) {}

public void windowDeiconified(WindowEvent arg0) {}

public void windowIconified(WindowEvent arg0) {}

public void windowOpened(WindowEvent arg0) {}

}

*Unelegant wäre wohl per FocusListener zu checken, wer dran ist und dann diesen hervorzuheben, z.B. durch die Textfarbe. Angesichts der einfachheit bei Buttons fände ich das aber ziemlich viel Aufwand.

Kommentare bzgl. der alllgemeinen Unzulänglichkeit von Swing, JAVA allgemein oder sonstige Flames lese ich - aber sie helfen mir hier nicht weiter. ;-)

mfg

Darkstar
2010-01-28, 20:15:24
Wenn man genau hinsieht, kann man sehen, daß der obere Slider-Knubbel anders aussieht als der untere – der Rand ist nicht schwarz sondern dunkelblau. (Es kann aber auch an der minderwertigen Qualität des Screenshosts liegen. :D Warum hast Du nicht PNG anstelle von GIF genommen?)

Käme vielleicht der Einsatz eines anderen Look&Feels wie z. B. Nimbus (http://java.sun.com/javase/6/docs/technotes/guides/jweb/otherFeatures/nimbus_laf.html) in Frage?

robobimbo
2010-01-28, 20:45:24
Gemacht wird was, wenn Du genau schaust, sieht der obere Slider anders aus als der untere, dh. es gibt einen Fokusmechanismus - aber ich muss dir zustimmen - das ist kaum und kaum zu sehen...


es gäbe eine (ziemlich witzlose methode) den dings selbst zu zeichnen:


package testing2;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JSlider;
import javax.swing.plaf.basic.BasicSliderUI;

public class MyJSliderUI extends BasicSliderUI {

public MyJSliderUI(JSlider b) {
super(b);
}


@Override
public void paintFocus(Graphics g) {
super.paintFocus(g);
Rectangle r = g.getClipBounds();
g.setColor(Color.BLACK);
g.draw3DRect(r.x, r.y, r.width, r.height, true);
}

}


In deinem Beispiel Programm brauchts dann zusätlich folgendes:


sl1 = new JSlider(JSlider.HORIZONTAL, 0, 10, 5);
sl2 = new JSlider(JSlider.HORIZONTAL, 0, 10, 5);
MyJSliderUI msui = new MyJSliderUI(sl1);
sl1.setUI(msui);


...aber da kommt halt das AWT Druch und das passt halt so gar nicht vom Design

Alternativ das Look und Feel halt anpassen, sollte möglich sein - aber damit hab ich mich noch überhaupt nicht beschäftigt:

http://www.java2s.com/Tutorial/Java/0240__Swing/CustomizingaJSliderLookandFeel.htm
http://www.rgagnon.com/javadetails/JavaUIDefaults.txt

Oder du findest ein anderes Look & Feel für deine Anwendung, wo der Sliderfokus deutlicher sichtbar ist.

Sephiroth
2010-01-28, 20:59:58
Sieht aus wie ein Problem des CrossPlatformLookAndFeel.

nutz doch stattdessen den viel schöneren System-LookAndFeel

public static void main(String[] argv) {
// System Look and Feel
try
{
javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelC lassName());
//javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getCrossPlatformLookA ndFeelClassName()); // default cross-platform LAF
}
catch (Exception unused)
{
// Ignore exception because we can't do anything. Will use default.
System.err.println("System-Look&Feel (LAF) not available");
}

TestingSliders ts = new TestingSliders();
ts.inti();
ts.setSize(300, 300);
ts.setVisible(true);
ts.addWindowListener(ts);
}

Pinoccio
2010-01-28, 23:08:23
Wenn man genau hinsieht, kann man sehen, daß der obere Slider-Knubbel anders aussieht als der untere – der Rand ist nicht schwarz sondern dunkelblau. (Es kann aber auch an der minderwertigen Qualität des Screenshosts liegen. :D Warum hast Du nicht PNG anstelle von GIF genommen?)Hm, scheint tatsächlich anders auszusehen. GIF ist, hm *Ausrede-such*, naja, steht halt im Alphabet und somit im Filetype-Auswahl-Dialog weiter vorne ...
Käme vielleicht der Einsatz eines anderen Look&Feels wie z. B. Nimbus (http://java.sun.com/javase/6/docs/technotes/guides/jweb/otherFeatures/nimbus_laf.html) in Frage?Nimbus, a cross platform look and feel introduced in the Java SE 6 update 10 release ist etwas ungünstig, da möglicherweise zu "neu". Aber sieht schonmal ziemlich gut aus. :-) (Das wäre Variante 2)
(Das Oracle-Logo auf der Seite ist ja äh ungewohnt. Muss ich mich auch erst dran gewöhnen.)es gäbe eine (ziemlich witzlose methode) den dings selbst zu zeichnen:Ja, so "unelegante" Lösungen hatte ich auch ins Auge gefasst. (Das wäre Variante 3)
Mein derzeitiger Favorit ist ein FocusListener und dann die Beschriftung des aktiven Sliders farblich hervorzuheben. (Das ist Variante 0)

Der zweite Slider ist der aktive
http://www.abload.de/thumb/bild105r8.png (http://www.abload.de/image.php?img=bild105r8.png)
PNG ;-)http://www.rgagnon.com/javadetails/JavaUIDefaults.txtAuch interessant! (Das wäre Variante 4)Sieht aus wie ein Problem des CrossPlatformLookAndFeel.

nutz doch stattdessen den viel schöneren System-LookAndFeel

public static void main(String[] argv) {
// System Look and Feel
try
{
javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelC lassName());
//javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getCrossPlatformLookA ndFeelClassName()); // default cross-platform LAF
}
catch (Exception unused)
{
// Ignore exception because we can't do anything. Will use default.
System.err.println("System-Look&Feel (LAF) not available");
}

TestingSliders ts = new TestingSliders();
ts.inti();
ts.setSize(300, 300);
ts.setVisible(true);
ts.addWindowListener(ts);
}Das versuch ich morgen mal. (Das wäre Variante 1)

Vielen Dank für die verschiedenen Tips. :smile:

mfg

Pinoccio
2010-01-28, 23:24:12
nutz doch stattdessen den viel schöneren System-LookAndFeelAussehen tut das super - zumindest hier unter Windows.

http://www.abload.de/img/bild2ruav.png (http://www.abload.de/image.php?img=bild2ruav.png)

Meine Hauptanwendung hat da auch keine Probleme mit (trotz einiger absolut positionierter Elemente).
Morgen schau ich mir das mal unter Linux an, wenn es da auch passt, dann bin ich glücklich. :)

mfg

DocEW
2010-01-29, 10:24:15
Morgen schau ich mir das mal unter Linux an, wenn es da auch passt, dann bin ich glücklich. :)
Sind wir glücklich? Vincent, sind wir glücklich?

Pinoccio
2010-01-29, 16:41:25
Sind wir glücklich? Vincent, sind wir glücklich?Ja, wir sind glücklich. :smile: (http://www.pulpfiction.de/neusprueche/gluecklich.mp3)

Danke nochmal.

mfg