フィールドのテキストをクリアする「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」ボタンのあるテキストフィールド)がすでに存在する場合は、代わりにそれを使用できる可能性があります。