2015-11-01 16 views
1

我試圖設計一個定製的Dialog,它允許用戶創建一個新的文件夾。直到我裝我的自定義外觀和感覺,一切看起來都只是罰款:JOptionPane沒有按鈕文字自定義LNF

Dialog without custom Look and Feel

現在,我嘗試設置外觀和按鈕的教科書中消失。

Dialog with custom Look and Feel

我建立了一個SSCCE這說明此問題。請注意,LNF類除了加載UIManager.getDefaults()的所有值外什麼也不做。如果這有幫助,我在Gnome 3.18.1上使用Debian 8(jessie),並且全局黑暗主題處於打開狀態。

爲什麼會發生這種情況,我該如何解決那些按鈕文本的消失?

+0

是否有任何理由,爲什麼你不只是使用'的JOptionPane提供的對話框'(它不會解決問題,但我只是好奇你爲什麼似乎正在通過箍環來實現你正在做的事情) – MadProgrammer

+1

@MadProgrammer因爲'JOptionPane.showInputDialog'不允許我檢查輸入是否有效,而不必顯示另一個對話框。 – mezzodrinker

+1

從我可以從JDK源代碼中推論出來,'BasicOptionPaneUI'使用'OptionPane.okButtonText'鍵從'UIManager'獲取'OK'按鈕的文本,'Cancel'使用'OptionPane'鍵.cancelButtonText',但這些不存儲在'UIDefaults'中,我還不確定它們存儲在哪裏 – MadProgrammer

回答

2

UIManager.getDefaults()檢索的值不包括JOptionPane按鈕的文本,其屬性分別爲OptionPane.cancelButtonTextOptionPane.okButtonText。這會導致按鈕顯示時沒有任何文本,導致它們與問題中提供的屏幕截圖一樣小。通過將OptionPane.cancelButtonTextOptionPane.okButtonText設置爲所需的值,JOptionPane按鈕將顯示設置文本。此解決方案也可能適用於「是/否」按鈕。

3

另一種常見的方法是使用UIDefaults#addResourceBundle(...)方法:

//@see javax/swing/plaf/basic/BasicLookAndFeel.java 
@Override 
public UIDefaults getDefaults() { 
    UIDefaults defaults = new UIDefaults(); 
    defaults.putAll(UIManager.getDefaults()); 
    //defaults.addResourceBundle("com.example.swing.plaf.light.resources.light"); 
    defaults.addResourceBundle("com.sun.swing.internal.plaf.basic.resources.basic"); 
    return defaults; 
} 

Test2.java

import java.awt.*; 
import java.io.File; 
import java.util.*; 
import javax.swing.*; 
import javax.swing.GroupLayout.Alignment; 
import javax.swing.GroupLayout.SequentialGroup; 

public class Test2 { 
    public static void main(String[] args) { 
     try { 
      UIManager.setLookAndFeel(new LightLookAndFeel()); 
      DialogFactory.showCreateFolderDialog(null, new File(".")); 
     } catch (UnsupportedLookAndFeelException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

class DialogFactory { 
    private DialogFactory() {} 

    public static void showCreateFolderDialog(Component component, File parent) { 
     JPanel panel = new JPanel(); 
     JLabel message = new JLabel("Please enter a folder name."); 
     JLabel label = new JLabel("Folder name:"); 
     final JLabel errorMessage = new JLabel(); 
     JTextField folderName = new JTextField(); 
     GroupLayout layout = new GroupLayout(panel); 
     layout.setHonorsVisibility(false); 
     layout.setAutoCreateContainerGaps(true); 
     layout.setAutoCreateGaps(true); 
     panel.setLayout(layout); 
     errorMessage.setVisible(false); 

     SequentialGroup hGroup = layout.createSequentialGroup(); 
     SequentialGroup input = layout.createSequentialGroup().addComponent(label).addComponent(folderName); 
     hGroup.addGroup(layout.createParallelGroup().addComponent(message).addGroup(input).addComponent(errorMessage)); 
     layout.setHorizontalGroup(hGroup); 

     SequentialGroup vGroup = layout.createSequentialGroup(); 
     vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(message)); 
     vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(label).addComponent(folderName)); 
     vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(errorMessage)); 
     layout.setVerticalGroup(vGroup); 

     final JOptionPane optionPane = new JOptionPane(panel, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION); 
     final JDialog dialog = new JDialog(JOptionPane.getFrameForComponent(component), "Create new folder", true); 
     dialog.setLocationRelativeTo(component); 
     dialog.setContentPane(optionPane); 
     dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); 
     optionPane.addPropertyChangeListener(event -> { 
      String property = event.getPropertyName(); 

      if (dialog.isVisible() && event.getSource() == optionPane && property.equals(JOptionPane.VALUE_PROPERTY)) { 
       if (folderName.getText().isEmpty() && (int) event.getNewValue() != JOptionPane.CANCEL_OPTION) { 
        errorMessage.setText("<html><body><b style='color: red'>Please enter a valid folder name!</b></body></html>"); 
        errorMessage.setVisible(true); 
        dialog.pack(); 
       } else { 
        dialog.setVisible(false); 
       } 
      } 
     }); 
     dialog.pack(); 
     dialog.setVisible(true); 

     int response = ((Integer) optionPane.getValue()).intValue(); 
     if (response != JOptionPane.OK_OPTION) return; 
     File newFolder = new File(parent, folderName.getText()); 
     newFolder.mkdirs(); 
    } 
} 

class LightLookAndFeel extends LookAndFeel { 
    private final UIDefaults defaults = new UIDefaults(); 

    public LightLookAndFeel() { 
     defaults.putAll(UIManager.getDefaults()); 
    } 

    @Override 
    public void initialize() { 
    } 

    @Override 
    public String getName() { 
     return "Light"; 
    } 

    @Override 
    public String getID() { 
     return getClass().getName(); 
    } 

    @Override 
    public String getDescription() { 
     return "Light Look and Feel"; 
    } 

    @Override 
    public boolean isNativeLookAndFeel() { 
     return false; 
    } 

    @Override 
    public boolean isSupportedLookAndFeel() { 
     return true; 
    } 

    @Override 
    public UIDefaults getDefaults() { 
     //defaults.addResourceBundle("com.example.swing.plaf.light.resources.light"); 
     defaults.addResourceBundle("com.sun.swing.internal.plaf.basic.resources.basic"); 
     return defaults; 
    } 
} 

// package com.example.swing.plaf.light.resources; 
// import java.util.*; 
// 
// public class light extends ListResourceBundle { 
//  @Override protected final Object[][] getContents() { 
//   return new Object[][] { 
//    //... 
//    { "OptionPane.cancelButtonMnemonic", "0" }, 
//    { "OptionPane.cancelButtonText", "Cancel" }, 
//    { "OptionPane.inputDialogTitle", "Input" }, 
//    { "OptionPane.messageDialogTitle", "Message" }, 
//    { "OptionPane.noButtonMnemonic", "78" }, 
//    { "OptionPane.noButtonText", "No" }, 
//    { "OptionPane.okButtonMnemonic", "0" }, 
//    { "OptionPane.okButtonText", "OKkkk" }, 
//    { "OptionPane.titleText", "Select an Option" }, 
//    { "OptionPane.yesButtonMnemonic", "89" }, 
//    { "OptionPane.yesButtonText", "Yessss" }, 
//    //... 
//   }; 
//  } 
// } 
// public class light_de extends ListResourceBundle { //... 
// public class light_es extends ListResourceBundle { //... 
// public class light_fr extends ListResourceBundle { //... 
// public class light_it extends ListResourceBundle { //... 
// public class light_ja extends ListResourceBundle { //... 
// public class light_ko extends ListResourceBundle { //... 
// public class light_pt_BR extends ListResourceBundle { //... 
// public class light_sv extends ListResourceBundle { //... 
// public class light_zh_CN extends ListResourceBundle { //... 
// public class light_zh_HK extends ListResourceBundle { //... 
// public class light_zh_TW extends ListResourceBundle { //... 
+0

這看起來像一個更復雜的,但通過'UIManager'設置'OptionPane.cancelButtonText'和'OptionPane.okButtonText'的好替代方案。 +1 – mezzodrinker