简体   繁体   中英

JTextField - Reset Border to System Default

I am trying to color the Border of a JTextField red and then change it back to "normal" later on. When I am using Linux (furthermore Ubuntu), the initial Border differs from the Border that you get by using UIManager.getBorder("TextField.border"); one of them is a SynthBorder and one is a FieldBorder . The "correct" one would be the SynthBorder .

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 );
  }
}

I have already tried:

  • using JComponent.updateUI() (no effect)
  • nulling the border (ruins the layout)
  • preserving it (not a proper way)

Does anyone have a better idea?

When you replace the Border try using:

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

When you use any wrapper class with "UIResource" this tell the LAF the component is part of the LAF and not a custom implementation

Then to restore the Border:

SwingUtilities.updateComponentTreeUI( tf );

Hopefully this will fake the UI into resetting the LAF properties, specifically the Border.

Read the section from the Swing tutorial on How to Set the LAF for more information.

Of course this is not as efficient as simply saving the Border and resetting it as all properties of the text field will be updated bye the updatComponentTreeUI(...) (if this works).

Still don't see why you can't save the Border. You could use the putClientProperty(...) method of the JComponent class to save the Border and then restore it using the getClientProperty(...) method.

You could even automate this by using adding a PropertyChangeListener to listen for a change in the border. When an event is generated if the getClientProperty(...) returns null, then you save the old value from the PropertyChangeEvent .

您可以使用以下代码在UIManager获取默认边框

jTextField2.setBorder(UIManager.getLookAndFeel().getDefaults().getBorder("TextField.border"));
yourJTextField.setBorder(new JTextField().getBorder());

You can get the border right after creating the component to save it, and set it again later.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM