2

フィールドのテキストをクリアする「x」ボタンを内部に持つテキストフィールドコンポーネントを作成しました。Windowのシステムルックアンドフィール(Windowsの場合)を使用する場合はうまく機能しますが、Nimbusを使用するときに正しい外観を取得しようとすると問題が発生します。つまり、button.setMargin(new Inset(0, 0, 0, 0)システムルックの場合とは異なり、ボタンの余白を変更できません。と感じます。

Nimbusを使用するときにマージンを設定するためのヘルプを探しましたが、これは一般的な問題のようです。余白を変更できる部分的な解決策を見つけることができましたが、すべてのボタンの余白が変更されるため、1つのボタンだけをデフォルトとは異なるものにしたいです。

'x'を表示するのに十分な大きさになるように、'x'文字列の境界から計算された'x'ボタンのサイズを明示的に設定しました。

Windowのシステムルックアンドフィールを使用した場合の結果。これは、私が探している一般的な外観です。

システムのルックアンドフィール

デフォルトのNimbusルックアンドフィールを使用した場合の結果。'x'は、Nimbusが許可するスペースをオーバーフローし、省略記号になります。

ニンバスのルックアンドフィール

Nimbusを使用してButton.contentMarginsをオーバーライドした場合の結果:「x」ボタンは正しく表示されますが、「test」ボタンはひどく表示されます。

ニンバスのルックアンドフィールに加えて、マージンのオーバーライド

ソースコード:

import java.awt.Graphics;
import java.awt.Insets;
import java.awt.geom.Rectangle2D;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.LookAndFeel;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.UnsupportedLookAndFeelException;

public class TextFieldTest {        
    public static void main(String[] args) {
        boolean useNimbusLookAndFeel    = false;
        boolean overrideNimbusDefaults  = false;
        String lafName = UIManager.getSystemLookAndFeelClassName();

        if ( useNimbusLookAndFeel ) {
            for ( LookAndFeelInfo info : UIManager.getInstalledLookAndFeels() ) {
                if ( "Nimbus".equals(info.getName()) ) {
                    lafName = info.getClassName();      
                    break;
                }
            }
        }

        try {
            UIManager.setLookAndFeel(lafName);              
        }
        catch (ClassNotFoundException e) {}
        catch (InstantiationException e) {}
        catch (IllegalAccessException e) {}
        catch (UnsupportedLookAndFeelException e) {}

        //Code to set override default button insets for Nimbus:
        if ( useNimbusLookAndFeel && overrideNimbusDefaults ) {
            LookAndFeel laf = UIManager.getLookAndFeel();               
            if ( laf != null ) {
                UIDefaults def = laf.getDefaults();
                def.put("Button.contentMargins", new Insets(0,0,0,0));
            }
        }       

        //Create frame:
        JPanel panel = new JPanel();        
        panel.add(new JButton("test"));
        panel.add(new DeletableTextField());

        JFrame frame = new JFrame();
        frame.getContentPane().add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }   

    static class DeletableTextField extends JTextField {
        JButton         mButton     = null;

        public DeletableTextField() {
            super(30);
            setup();
        }

        private void setup() {
            mButton = new JButton("x");
            mButton.setMargin(new Insets(0, 0, 0, 0));
            add(mButton);
        }

        @Override
        public void paint(Graphics g) {
            g.setFont(mButton.getFont());
            Rectangle2D rect    = g.getFontMetrics().getStringBounds(mButton.getText(), g);
            int stringWidth     = (int)rect.getWidth();

            int topOffset       = 3;
            int rightOffset     = 3;
            int bottomOffset    = 3;
            int width           = (int)Math.ceil(stringWidth * 2.5);
            int height          = getHeight() - (bottomOffset + topOffset);         
            int x_coord         = getWidth() - (rightOffset + width);

            mButton.setMargin(new Insets(0, 0, 0, 0));
            mButton.setBounds(x_coord, topOffset, width, height);

            super.paint(g);
        }
    }
}

自分の「x」を上にペイントするなど、他の方法でもこれを実現できることは承知していますが、現在のルックアンドフィールのボタンペイント機能を利用して、統一された外観を実現できると便利だと思いました。

したがって、すべてのボタンのマージンを変更せずに、ニンバスのルックアンドフィールを使用するときに単一のJButtonのマージンを変更する方法があるかどうかを尋ねたいと思います。または、似たようなスイングコンポーネント(「x」ボタンのあるテキストフィールド)がすでに存在する場合は、代わりにそれを使用できる可能性があります。

4

3 に答える 3

7

Nimbus は、LAF プロパティのインスタンスごとのオーバーライドをサポートしています。コンテキストでは、次のようになります。

  mButton = new JButton("x");
  UIDefaults def = new UIDefaults();
  def.put("Button.contentMargins", new Insets(0,0,0,0));
  mButton.putClientProperty("Nimbus.Overrides", def);
于 2012-01-07T11:34:39.013 に答える
1

たぶん、ハックとして、左/右の挿入値を試して、それらをゼロ以外にして、テキストが両方のLAFに表示されるようにすることができます。

自分の「x」を上にペイントするなど、他の方法でこれを達成できることを認識しています。

その場合は、TextIconクラスを使用してカスタムペイントを行うことができます。

于 2012-01-06T22:04:03.320 に答える