2017-04-18 5 views
0

Ich versuche, die Border eines JTextField rot zu färben und dann später wieder auf "normal" zu ändern. Wenn ich Linux (Ubuntu) benutze, unterscheidet sich die ursprüngliche Border von der Border, die Sie mit UIManager.getBorder("TextField.border"); erhalten, von denen eine SynthBorder ist und eine FieldBorder ist. Der "richtige" wäre der SynthBorder.JTextField - Rand auf Systemstandard zurücksetzen

SSCCE:

import javax.swing.BorderFactory; 
import javax.swing.BoxLayout; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JTextField; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Main 
{ 
    private static boolean switched; 

    public static void main(final String[] args) 
     throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException 
    { 
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 

    JFrame frame = new JFrame("Test border change"); 
    frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.LINE_AXIS)); 
    JTextField tf = new JTextField(); 
    JButton button = new JButton("Switch"); 
    button.addActionListener(action -> 
    { 
     if (switched) 
     { 
     tf.setBorder(UIManager.getBorder("TextField.border")); 
     switched = !switched; 
     } 
     else 
     { 
     tf.setBorder(BorderFactory.createLineBorder(Color.RED)); 
     switched = !switched; 
     } 
    }); 
    frame.getContentPane().add(tf); 
    frame.getContentPane().add(button); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.pack(); 
    frame.setVisible(true); 
    } 
} 

Ich habe bereits versucht:

  • JComponent.updateUI() (No Effect)
  • nulling die Grenze (Ruinen das Layout)
  • Erhaltung es (keine richtige Verwendung Weg)

Hoffe, dass jemand eine bessere Idee hat.

Bezug auf Marcel

+0

Mögliche Duplikate von [Zurücksetzen/entfernen Sie einen Rand in Swing] (http://StackOverflow.com/Questions/726808/Reset-Remove-A-Border-Ins-Swing) – Berger

+0

Ich habe das schon versucht, funktioniert gut in das Beispiel, aber löst Ausnahmen im produktiven Anwendungsfall wegen der Vielseitigkeit aus. Ich denke aber weiter darüber nach. – ScriptKiddy

+1

Ein Kommentar zu einer Antwort in dem obigen Link schlägt vor, 'setBorder (null)' aufzurufen, bevor 'updateUI() 'aufgerufen wird. – Berger

Antwort

2

Wenn Sie die Grenze versuchen ersetzen:

Border uiBorder = BorderUIResource(BorderFactory.createLineBorder(Color.RED)); 
tf.setBorder(uiBorder); 

Wenn Sie eine Wrapper-Klasse verwenden, um mit „UIResource“ dies den LAF sagen, das Bestandteil des LAF ist und nicht eine benutzerdefinierte Implementierung

dann die Grenze wiederherzustellen:

SwingUtilities.updateComponentTreeUI(tf); 

Hoffentlich wird diese Fälschung der UI in Zurücksetzen der LAF-Eigenschaften, insbesondere des Rahmens.

Lesen Sie den Abschnitt aus dem Swing-Tutorial auf How to Set the LAF für weitere Informationen.

Natürlich ist das nicht so effizient wie einfach den Border speichern und zurücksetzen, da alle Eigenschaften des Textfelds durch die updatComponentTreeUI(...) aktualisiert werden (wenn das funktioniert).

Immer noch nicht sehen, warum Sie die Grenze nicht speichern können. Sie können die putClientProperty(...)-Methode der JComponent-Klasse verwenden, um den Rahmen zu speichern und ihn dann mit der getClientProperty(...)-Methode wiederherzustellen.

Sie können dies sogar automatisieren, indem Sie eine PropertyChangeListener hinzufügen, um auf eine Änderung der Grenze zu achten. Wenn ein Ereignis generiert wird, wenn getClientProperty(...) Null zurückgibt, speichern Sie den alten Wert aus PropertyChangeEvent.

+0

Ich werde mit den put/getClientProperty Methoden beibehalten. Auch funktioniert uodateComponentTreeUI gut, aber konservieren passt leider besser zu meinem Fall; D – ScriptKiddy

0

Sie können die Grenze bekommen direkt nach dem Erstellen der Komponente, es zu speichern, und legen Sie es später noch einmal. mit

Border defaultBorder = tf.getBorder(); 
... 
tf.setBorder(defaultBorder); 
+0

Konservieren ist keine Option, D – ScriptKiddy

+0

@ScriptKiddy, 'Konservieren ist keine Option' - warum nicht? – camickr