JComboBox显示不可见的下拉菜单

时间:2012-10-03 15:50:31

标签: java swing printing jcombobox jpopup

这是我关于stackoverflow的第一个问题,我需要一些帮助。

作为更宏大的java应用程序的一部分,我想提出一个带有几个JComboBox的JDialog,查询用户选择要使用的打印机,然后选择要打印的关联分辨率。

但是,如果我选择一台打印机并且我选择的分辨率在多台打印机之间共享,那么当我选择包含相同分辨率的打印机时,为分辨率组合框显示的下拉菜单是不可见的。下拉菜单的大小是正确的,它只是没有填充。试试我的代码,你会明白我的意思。 例如,我的两个打印选项是Win32打印机:Kyocera FS-1035MFP KX和Win32打印机:Adobe PDF(打印到pdf)。它们共享分辨率300x300,所以如果我为Kyocera选择此分辨率然后选择Adobe PDF打印机,下拉菜单将是正确的大小,但将为空。

我不确定发生了什么。希望有人可以帮助我。谢谢你的时间。

import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Vector;
import javax.print.DocFlavor;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.PrinterResolution;
import javax.swing.*;

public final class ComboDemo extends JDialog {

    private JComboBox selectPrinterBox;
    private JLabel selectPrinterLabel;
    private JComboBox selectResolutionBox;
    private JLabel selectResolutionLabel;
    private PrintService printService;
    private Resolution resolution;
    private DocFlavor flavor;
    private PrintRequestAttributeSet aset;
    private Vector<Resolution> resolutionVector;
    private double xDPI = 300.0;
    private double yDPI = 300.0;

    public PrintService[] getPrintServices() {
        this.flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
        this.aset = new HashPrintRequestAttributeSet();

        return PrintServiceLookup.lookupPrintServices(flavor, aset);
    }

    public Vector<Resolution> getVectorOfResolutions(PrintService service) {
        PrinterResolution[] supportedResolutions =
                (PrinterResolution[]) service.getSupportedAttributeValues(
                javax.print.attribute.standard.PrinterResolution.class,
                flavor, aset);
        Vector<Resolution> resolutions = new Vector<Resolution>();
        for (PrinterResolution supportedResolution : supportedResolutions) {
            Resolution res = new Resolution();
            res.setxDPI(supportedResolution.getResolution(PrinterResolution.DPI)[0]);
            res.setyDPI(supportedResolution.getResolution(PrinterResolution.DPI)[1]);
            resolutions.add(res);
        }

        return resolutions;
    }

    public ComboDemo() {

        super();
        initComponents();
        setContent();
        setItemListeners();

    }

    public void initComponents() {

        this.selectPrinterLabel = new JLabel("Select Printer: ");

        PrintService[] services = this.getPrintServices();
        this.selectPrinterBox = new JComboBox(services);

        this.printService = (PrintService) this.selectPrinterBox.getSelectedItem();
        this.resolutionVector = this.getVectorOfResolutions(printService);

        this.resolution = new Resolution();
        this.selectResolutionLabel = new JLabel("Select Resolution: ");
        this.selectResolutionBox = new JComboBox(this.resolutionVector);
    }

    public void setContent() {

        JPanel selectPrinterPanel = new JPanel();
        selectPrinterPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
        selectPrinterPanel.add(selectPrinterLabel);
        selectPrinterPanel.add(selectPrinterBox);

        JPanel selectResolutionPanel = new JPanel();
        selectResolutionPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
        selectResolutionPanel.add(selectResolutionLabel);
        selectResolutionPanel.add(selectResolutionBox);

        JPanel mainPanel = new JPanel();
        BoxLayout fP = new BoxLayout(mainPanel, BoxLayout.Y_AXIS);
        mainPanel.setLayout(fP);
        mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
        mainPanel.add(selectPrinterPanel);
        mainPanel.add(selectResolutionPanel);

        this.setContentPane(mainPanel);
        this.setTitle("ComboDemo");
        this.setLocation(85, 79);
        this.pack();

    }

    public void setItemListeners() {

        selectPrinterBox.addItemListener(
                new ItemListener() {

                    @Override
                    public void itemStateChanged(ItemEvent evt) {
                        if (evt.getSource().equals(selectPrinterBox)) {
                            if (evt.getStateChange() == ItemEvent.SELECTED) {
                                System.out.println("in printerBox itemListener");
                                printService = (PrintService) selectPrinterBox.getSelectedItem();
                                resolution = (Resolution) selectResolutionBox.getSelectedItem();
                                System.out.println("resolution (PrinterBox) : " + resolution.toString());
                                resolutionVector.clear();
                                resolutionVector.addAll(getVectorOfResolutions(printService));
                                if (resolutionVector == null) {
                                    System.out.println("resVec is null");
                                }
                                if (resolutionVector.contains(resolution)) {
                                    selectResolutionBox.setSelectedIndex(resolutionVector.lastIndexOf(resolution));

                                } else {
                                    selectResolutionBox.setSelectedIndex(0);
                                }
                            }
                        }

                    }
                });

        selectResolutionBox.addItemListener(
                new ItemListener() {

                    @Override
                    public void itemStateChanged(ItemEvent evt) {
                        if (evt.getSource().equals(selectResolutionBox)) {
                            if (evt.getStateChange() == ItemEvent.SELECTED) {
                                System.out.println("in resolutionBox itemListener");
                                resolution = (Resolution) selectResolutionBox.getSelectedItem();
                                System.out.println("resolution (ResolutionBox) : " + resolution.toString());
                                xDPI = (double) resolution.getxDPI();
                                yDPI = (double) resolution.getyDPI();
                            }
                        }
                    }
                });

    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                ComboDemo cd = new ComboDemo();
                cd.setVisible(true);

            }
        });
    }
}

class Resolution {

    private int xDPI;
    private int yDPI;

    public int getxDPI() {
        return xDPI;
    }

    public void setxDPI(int xDPI) {
        this.xDPI = xDPI;
    }

    public int getyDPI() {
        return yDPI;
    }

    public void setyDPI(int yDPI) {
        this.yDPI = yDPI;
    }

    @Override
    public String toString() {
        return (this.getxDPI() + "x" + this.getyDPI());
    }

    @Override
    public boolean equals(Object obj) {
        if ( obj instanceof Resolution ) {
            Resolution r = (Resolution) obj;
            return (this.xDPI == r.xDPI) && (this.yDPI == r.yDPI);
        }
        return false;
    }

    @Override
    public int hashCode() {
      return (this.getxDPI()*1000)+ this.getyDPI();  
    }
}

1 个答案:

答案 0 :(得分:1)

问题在于,您正在操纵Vector备份您正在使用的隐式ComboBoxModel,位于ComboBoxModel的后面。如果未包含分辨率,则调用setSelectedIndex(0),最终会触发刷新组合框的项目(因为JComboBox / DefaultComboBoxModel的内部扭曲。

所以:

  1. 要么使用ComboBoxModel,要修改JComboBox的内容,请使用ComboBoxModel(请查看DefaultComboBoxModel
  2. 或使用JComboBox API(removeAllItemsaddItem
  3. 在组合框上使用ActionListener。而不是ItemListener您只会收到“选择更改”事件的通知