我在更改文件追踪器中附件组件的位置时遇到问题。
我通过在文件选择器的附件组件中放置一个复选框来自定义保存文件对话框。但是复选框的位置不好,真的很难看。
我可以将附件组件移动到文件窗格下面吗?怎么做?
或者,如果您有其他解决方案可以做同样的事情,也欢迎。
谢谢你们。
我使用以下代码添加复选框:
JFileChooser fc = new JFileChooser(file)
JPanel accessory = new JPanel();
JCheckBox isOpenBox = new JCheckBox("Open file after saving");
accessory.setLayout(new BorderLayout());
accessory.add(isOpenBox, BorderLayout.SOUTH);
fc.setAccessory(accessory);
在此屏幕截图中,复选框的位置不佳。
此屏幕截图正是我想要的效果。
答案 0 :(得分:10)
“正确”的方式是构建符合您要求的新UI /外观代理。问题是,您需要执行此操作的详细信息(以OO方式)隐藏,private
没有公共/受保护的访问者或本地定义...这是大多数L& F的主要问题代表们......谢谢你们......
所以,你最终会复制并粘贴整个课程,只是为了你可以添加这个功能......你需要为你想支持的每个平台做这个...
“不太理想”的方式是在JFileChooser
内徘徊,并拉出你需要“改造”你的要求的那些元素。这很麻烦,它容易出错,它会做出假设并且很容易破解。
就个人而言,如果我要删除这个特定的轨道,我会创建一个实用程序类,它提供一个简单的public
,static
方法,允许我传递{{1}的实例并且基于当前平台(和/或当前的外观),对我进行更改...或者可以自动生成JFileChooser
修改以满足这些要求的工厂类。但这只是一个想法...
让我重复一遍,对于一个非常糟糕的设计问题,这是一个非常糟糕的想法,并且旨在证明:1-试图修改外观和感觉的问题; 2-试图以这种方式完成这项工作所面临的问题和问题......
JFileChooser
不,我不自豪......需要用漂白剂去洗眼睛和大脑...... icky ......
已更新为Mac支持
对于那些想要Mac版的人来说......
这进一步凸显了这种方法的“片状”,打破它不会花太多时间......
import java.awt.Component;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFileChooser fc = new JFileChooser();
List<JTextField> fields = findAll(JTextField.class, fc);
if (fields.size() == 1) {
JTextField fieldNameField = fields.get(0);
Container parent = fieldNameField.getParent();
JCheckBox cb = new JCheckBox("Open file after saving");
JComboBox fileTypes = findAll(JComboBox.class, parent).get(0);
parent.setLayout(new GridBagLayout());
parent.removeAll();
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
gbc.insets = new Insets(2, 2, 4, 2);
parent.add(fieldNameField, gbc); // file name field...
gbc.gridx++;
gbc.weightx = 0;
parent.add(cb, gbc); // Check box
gbc.gridx = 0;
gbc.gridy++;
gbc.gridwidth = GridBagConstraints.REMAINDER;
parent.add(fileTypes, gbc); // File types
} else {
System.out.println("Found to many results?!");
}
fc.showOpenDialog(null);
}
});
}
public <T extends Component> List<T> findAll(Class<? extends T> aClass, Container parent) {
List<T> matches = new ArrayList<>();
for (Component child : parent.getComponents()) {
if (aClass.isInstance(child)) {
matches.add((T)child);
}
if (child instanceof Container) {
matches.addAll(findAll(aClass, (Container)child));
}
}
return matches;
}
}
已更新为基于import java.awt.Component;
import java.awt.Container;
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFileChooser fc = new JFileChooser();
List<JLabel> labels = findAll(JLabel.class, fc);
JCheckBox cb = new JCheckBox("Open file after saving");
JLabel fileFormatLabel = null;
for (JLabel label : labels) {
if ("File Format:".equals(label.getText())) {
fileFormatLabel = label;
}
}
System.out.println(fileFormatLabel);
if (fileFormatLabel != null) {
Container parent = fileFormatLabel.getParent();
parent.add(cb);
}
fc.showOpenDialog(null);
}
});
}
public <T extends Component> List<T> findAll(Class<? extends T> aClass, Container parent) {
List<T> matches = new ArrayList<>();
for (Component child : parent.getComponents()) {
if (aClass.isInstance(child)) {
matches.add((T) child);
}
if (child instanceof Container) {
matches.addAll(findAll(aClass, (Container) child));
}
}
return matches;
}
}
的搜索
这使用Locale
FileChooser.filesOfTypeLabelText
查找UIManager.getString
密钥的文本,理论上应该使其成为(稍微)更好的跨平台解决方案......至少它使它在mac上工作得更好......
这也说明了必须开始支持多个操作系统的混乱...因为我只有两个......
File Format:
更新了反思......
由于我已经为以前的“黑客”打算编程地狱,我不妨投入一个使用反射来查找字段的例子。
现在,您可以通过多种方式执行此操作,例如,您可以按类型列出所有字段,并检查各种属性以确定您想要的内容。如果您不知道实际的字段名称,则会使用此名称。如果您有权访问源代码,则可以直接查找字段名称,如本示例所示
import java.awt.Component;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test1 {
public static void main(String[] args) {
new Test1();
}
public Test1() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFileChooser fc = new JFileChooser();
JCheckBox cb = new JCheckBox("Open file after saving");
if (System.getProperty("os.name").startsWith("Windows 7")) {
List<JTextField> fields = findAll(JTextField.class, fc);
if (fields.size() == 1) {
JTextField fieldNameField = fields.get(0);
Container parent = fieldNameField.getParent();
JComboBox fileTypes = findAll(JComboBox.class, parent).get(0);
parent.setLayout(new GridBagLayout());
parent.removeAll();
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
gbc.insets = new Insets(2, 2, 4, 2);
parent.add(fieldNameField, gbc); // file name field...
gbc.gridx++;
gbc.weightx = 0;
parent.add(cb, gbc); // Check box
gbc.gridx = 0;
gbc.gridy++;
gbc.gridwidth = GridBagConstraints.REMAINDER;
parent.add(fileTypes, gbc); // File types
}
} else if (System.getProperty("os.name").startsWith("Mac OS X")) {
Locale l = fc.getLocale();
JLabel fileFormatLabel = findLabelByText(fc, UIManager.getString("FileChooser.filesOfTypeLabelText", l), "Format:");
if (fileFormatLabel != null) {
Container parent = fileFormatLabel.getParent();
System.out.println("");
parent.add(cb);
}
}
fc.showOpenDialog(null);
}
});
}
public JLabel findLabelByText(Container parent, String... texts) {
JLabel find = null;
List<JLabel> labels = findAll(JLabel.class, parent);
for (JLabel label : labels) {
for (String text : texts) {
if (text.equals(label.getText())) {
find = label;
break;
}
}
}
return find;
}
public <T extends Component> List<T> findAll(Class<? extends T> aClass, Container parent) {
List<T> matches = new ArrayList<>();
for (Component child : parent.getComponents()) {
if (aClass.isInstance(child)) {
matches.add((T) child);
}
if (child instanceof Container) {
matches.addAll(findAll(aClass, (Container) child));
}
}
return matches;
}
}
记住:仅仅因为你可以做某事,并不代表你应该做的事情!