Вы можете использовать SpringLayout
в JLayeredPane
следующим образом:
import java.awt.Dimension;
import java.awt.Font;
import javax.swing.AbstractButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPasswordField;
import javax.swing.SpringLayout;
import javax.swing.SwingUtilities;
public class Main {
private static void createAndShowGUI() {
final AbstractButton show = new JCheckBox("Show");
//Just hide every decorating colors:
show.setBorderPainted(false);
show.setContentAreaFilled(false);
show.setFocusPainted(false);
final JPasswordField pass = new JPasswordField(20);
pass.setFont(new Font(Font.MONOSPACED, Font.PLAIN, pass.getFont().getSize()));
final char echo = pass.getEchoChar();
show.addActionListener(e -> {
pass.setEchoChar(show.isSelected()? 0: echo);
pass.requestFocusInWindow();
});
//Put the fields in a JLayeredPane:
final JLayeredPane pane = new JLayeredPane();
pane.setLayout(new SpringLayout());
pane.add(pass, JLayeredPane.DEFAULT_LAYER);
pane.add(show, JLayeredPane.PALETTE_LAYER); //Layer over the DEFAULT_LAYER one.
//Setup the layout of the pane:
final SpringLayout layout = (SpringLayout) pane.getLayout();
layout.putConstraint(SpringLayout.WEST, pass, 0, SpringLayout.WEST, pane);
layout.putConstraint(SpringLayout.EAST, pass, 0, SpringLayout.EAST, pane);
layout.putConstraint(SpringLayout.NORTH, pass, 0, SpringLayout.NORTH, pane);
layout.putConstraint(SpringLayout.SOUTH, pass, 0, SpringLayout.SOUTH, pane);
layout.putConstraint(SpringLayout.EAST, show, 0, SpringLayout.EAST, pane);
layout.putConstraint(SpringLayout.NORTH, show, 0, SpringLayout.NORTH, pane);
layout.putConstraint(SpringLayout.SOUTH, show, 0, SpringLayout.SOUTH, pane);
//Set the preferred size of the pane (it's not automatic with SpringLayout):
final Dimension showPrefSz = show.getPreferredSize(),
passPrefSz = pass.getPreferredSize();
pane.setPreferredSize(new Dimension(showPrefSz.width + passPrefSz.width, Math.max(showPrefSz.height, passPrefSz.height)));
final JFrame frame = new JFrame("Unmaskable password field");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(pane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(Main::createAndShowGUI);
}
}
Любой Component
будет работать, так что вы можете поставить JButton
с глазом значок вместо JCheckBox
, который я использую.
Я предполагаю, что вы собираетесь setBorderPainted(false)
, setContentAreaFilled(false)
и setFocusPainted(false)
на кнопке, если это вообще необходимо.
Помните, что в соответствии с документами вы не должны звонить setOpaque(false)
на AbstractButton
и вместо этого использовать setContentAreaFilled(false)
.
Вот соответствующие Java учебные пособия:
- Как использовать SpringLayout .
- Как использовать многоуровневые панели .
The SpringLayout.putConstraint
Команды, которые я использую в MRE, сначала говорят LayoutManager
, чтобы заполнить весь JLayeredPane
JTextComponent
(4 первые команды), а затем вставляют JCheckBox
на восточной стороне JLayeredPane
и также заполните всю высоту JLayeredPane
JCheckBox
, что делает текст и флажок компонента JCheckBox
вертикально центрированными (3 последние команды).
Примечание: вам нужно установить предпочтительный размер JLayeredPane
, потому что SpringLayout
не скажет ему предпочтительный размер в соответствии с компонентами (такими как другие LayoutManager
s).