gpt4 book ai didi

java - 在文件选择器中更改附件组件的位置

转载 作者:行者123 更新时间:2023-12-03 19:00:28 25 4
gpt4 key购买 nike

我在更改文件选择器中附件组件的位置时遇到问题。

我通过在文件选择器的附件组件中放置一个复选框来自定​​义保存文件对话框。但是复选框的位置不好,真的很难看。

我可以将附件组件移动到文件 Pane 下方吗?怎么做?

或者,如果您有其他解决方案来做同样的事情,也欢迎。

谢谢你们。

我使用以下代码添加复选框:

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

在这个截图中,复选框的位置不好。

enter image description here

这个截图正是我想要的效果。

enter image description here

最佳答案

“正确”的方法是构建一个满足您要求的新 UI/外观委托(delegate)。问题是,您需要执行此操作的细节(以 OO 方式)被隐藏了,private没有公共(public)/ protected 访问器或在本地定义...这是大多数 L&F 代表的主要问题...谢谢大家...

所以,你最终会复制和粘贴整个类(class),这样你就可以添加这个功能......你需要为你想要支持的每个平台都这样做......

“不太理想”的方法是在 JFileChooser 内搜索。并提取您需要“改造”您的要求的那些元素。这很困惑,很容易出错,它会做出假设并且会非常非常容易地崩溃。

就个人而言,如果我要走这条特定的轨道,我会创建一个实用程序类,它提供一个简单的 public , static允许我传递 JFileChooser 实例的方法并拥有它,基于当前平台(和/或当前外观和感觉),为我进行更改...或可以自动生成 JFileChooser 的工厂类修改以满足这些要求...但这只是一个想法...

让我重申一下,这对于一个非常糟糕的设计问题来说是一个非常糟糕的主意,并且旨在证明: 1- 尝试修改外观的问题; 2-您在尝试按照希望的方式进行这项工作时将面临的问题和问题......

File Chooser

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

}

不,我并不骄傲……需要用漂白剂洗我的眼睛和大脑……恶心……

更新了 Mac 支持

对于那些想要 Mac 版本的人...

Mac File Chooser

这只是进一步突出了这种方法的“脆弱性”,打破它并不需要太多......
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查找 File Format: 的文本关键,理论上,应该使它成为一个(稍微)更好的跨平台解决方案......至少它使它在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 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;
}

}

用反射更新...

由于我已经为以前的“黑客”而去程序员 hell ,我不妨举一个使用反射来查找字段的示例。

现在,您可以通过多种方式执行此操作,例如,您可以按类型列出所有字段,并检查各种属性以确定您想要什么。这将在您不知道实际字段名称时使用,或者,如果您可以访问源代码,则可以直接查找字段名称,如本示例中所做的那样
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.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
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;
import javax.swing.plaf.FileChooserUI;

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")) {

try {
JTextField filenameTextField = (JTextField) getField("filenameTextField", fc.getUI());
JComboBox filterComboBox = (JComboBox) getField("filterComboBox", fc.getUI());

System.out.println(filenameTextField);
System.out.println(filterComboBox);

Container parent = filenameTextField.getParent();

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(filenameTextField, 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(filterComboBox, gbc); // File types
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
ex.printStackTrace();
}
} else if (System.getProperty("os.name").startsWith("Mac OS X")) {

try {
JComboBox filterComboBox = (JComboBox) getField("filterComboBox", fc.getUI());
Container parent = filterComboBox.getParent();
parent.add(cb);
} catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException ex) {
ex.printStackTrace();
}
}

fc.showOpenDialog(null);
}

});
}

private Object getField(String name, Object parent) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
Class aClass = parent.getClass();
Field field = aClass.getDeclaredField(name);
field.setAccessible(true);
return field.get(parent);
}

}

记住:仅仅因为您可以做某事,并不意味着您应该做某事!

关于java - 在文件选择器中更改附件组件的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25538213/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com