java - JComboBox 显示不可见的下拉菜单

标签 java swing printing jcombobox jpopup

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

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

但是,如果我选择一台打印机并且我选择的分辨率在多台打印机之间共享,那么当我选择一台包含相同分辨率的打印机时,为分辨率组合框显示的下拉菜单是不可见的。下拉菜单的大小是正确的,只是没有填充。试试我的代码,您就会明白我的意思。 例如,我的两个打印选项是 Win32 Printer : Kyocera FS-1035MFP KX 和 Win32 Printer : Adob​​e PDF(打印为 pdf)。它们共享 300x300 分辨率,因此如果我为 Kyocera 选择此分辨率,然后选择 Adob​​e 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();  
    }
}

最佳答案

问题是您正在操作 Vector,它支持您正在使用的隐式 ComboBoxModel,在 ComboBoxModel 的背后。如果不包含分辨率,您调用 setSelectedIndex(0) 最终触发组合框项目的刷新(因为 JComboBox/DefaultComboBoxModel

所以:

  1. 要么使用 ComboBoxModel,当您想要修改 JComboBox 的内容时,使用 ComboBoxModel 进行修改(查看 DefaultComboBoxModel)
  2. 或者使用JComboBox API (removeAllItems, addItem)
  3. 在组合框上使用 ActionListener。而不是 ItemListener 您只会收到“selection-change”事件的通知

关于java - JComboBox 显示不可见的下拉菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12712164/

相关文章:

java - 使 JSVGScrollPane 内的 JSVGCanvas 与 SVGDocument 大小匹配

c# - 自动将文字换行到打印页面?

python - 在 Python 3.4 中打印变量

java - un 使用java转义特殊字符

java - 运行 EMR 时出现 "Error: Could not find or load main class"?

java - 如何使 Paging 库与 reverse recyclerview 一起工作?

java打印字符串给出指针编号

java - 从 Applet 向 servlet 发送数据时出现 EOFException

java - 文件选择器选择了错误的导出目录

Java 操作监听器从源更改对象