簡體   English   中英

在JFileChooser中調整JList文件元素的大小

[英]Resize JList file elements in JFileChooser

我有一個JFileChooser 我正在嘗試向文件JList添加縮放功能。

我想為列表的每個元素更改文件名和文件圖標的比例因子。

我們如何實現這一目標?

好吧,我發現了一些丑陋的懶家伙。 它可能不僅是您想要的,而且是一個很好的起點(並且相當簡單):

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.plaf.basic.BasicListUI;

public class TJFileChooserDemo {

    //Obtains the (first) JList which is found inside the component/container:
    public static JList getFirstJList(final Component component) {
        if (component instanceof JList)
            return (JList) component;
        if (component instanceof Container)
            for (int i=0; i<((Container)component).getComponentCount(); ++i) {
                final JList list = getFirstJList(((Container)component).getComponent(i));
                if (list != null)
                    return list;
            }
        return null;
        //As you can see, it's a bit lazy hack, which has to run for every JFileChooser once at start-up.
    }

    private static final double SCALE_STEP_SIZE = 0.125; //Smaller values of this makes zooming slower. Greater values makes zooming faster.
    private static double scaleFactor = 1;

    public static class TJListCellRenderer extends DefaultListCellRenderer {
        public TJListCellRenderer() {
            //Ensure every pixel is painted starting from the top-left corner of the label:
            super.setVerticalAlignment(JLabel.TOP);
            super.setHorizontalAlignment(JLabel.LEFT);
            //We need to do this, because the scaling in paintComponent() is also relative to the top-left corner.
        }

        @Override
        public void paintComponent(final Graphics g) {
            //setRenderingHints here? Probably for ANTIALIAS...
            ((Graphics2D)g).scale(scaleFactor, scaleFactor); //Let's scale everything that is painted afterwards:
            super.paintComponent(g); //Let's paint the (scaled) JLabel!
        }

        @Override
        public Dimension getPreferredSize() {
            final Dimension superPrefDim = super.getPreferredSize(); //Handles automatically insets, icon size, text font, etc.
            final double w = superPrefDim.width * scaleFactor, //And we just scale the preferred size.
                         h = superPrefDim.height * scaleFactor; //And we just scale the preferred size.
            return new Dimension((int)w + 5, (int)h + 5); //Add 5 extra pixels to spare.
        }

        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
//            System.out.println(value.getClass()); //Something ugly...
            return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        }
    }

    public static class TJListUI extends BasicListUI {
        @Override
        public void updateLayoutState() {
            super.updateLayoutState(); //Just make the following method public.
            /*Note: this is not really needed here:
            The method could remain protected, but in the case you want this
            code to be a bit more reusable, then you shall make it public.*/
        }
    }

    public static void main(final String[] args) {
        final JFileChooser jfc = new JFileChooser();
        jfc.setDialogType(JFileChooser.OPEN_DIALOG);

        final TJListUI ui = new TJListUI();

        final JList list = getFirstJList(jfc);
        list.setUI(ui);
        list.setCellRenderer(new TJListCellRenderer());

        final JButton buttonZoomIn = new JButton("Zoom in"),
                      buttonZoomOut = new JButton("Zoom out"),
                      buttonResetZoom = new JButton("Reset zoom");

        buttonZoomIn.addActionListener(e -> {
            scaleFactor = scaleFactor + SCALE_STEP_SIZE;
            ui.updateLayoutState(); //Read the preferred sizes from the cell renderer.
            list.revalidate(); //Update the JScrollPane.
            list.repaint(); //Repaint the list.
        });

        buttonZoomOut.addActionListener(e -> {
            scaleFactor = Math.max(scaleFactor - SCALE_STEP_SIZE, SCALE_STEP_SIZE); //Do not allow underflow.
            ui.updateLayoutState(); //Read the preferred sizes from the cell renderer.
            list.revalidate(); //Update the JScrollPane.
            list.repaint(); //Repaint the list.
        });

        buttonResetZoom.addActionListener(e -> {
            scaleFactor = 1;
            ui.updateLayoutState(); //Read the preferred sizes from the cell renderer.
            list.revalidate(); //Update the JScrollPane.
            list.repaint(); //Repaint the list.
        });

        final JPanel buttons = new JPanel(); //FlowLayout.
        buttons.add(buttonZoomIn);
        buttons.add(buttonZoomOut);
        buttons.add(buttonResetZoom);

        final JPanel panel = new JPanel(new BorderLayout());
        panel.add(buttons, BorderLayout.PAGE_START);
        panel.add(jfc, BorderLayout.CENTER);

        final JFrame frame = new JFrame("JFileChooser's JList cell sizes demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(panel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

或者,您可以在此處查看有關JList單獨調整大小的單元格的答案。

您也可以添加JFileChooser的用於放大/縮小的按鈕作為附件 閱讀簡單示例以了解操作方法。

測試此代碼,我正在等待評論...

最后,我意識到不需要縮放文本。

為了獲得圖像文件縮略圖,我使用了使JFileChooser顯示圖像縮略圖的代碼-檢查BoffinbraiN答案。

然后進行縮放:

1)在ThumbnailFileChooser的按鈕上添加一個ActionListener

public class ZoomListener implements ActionListener {
    private boolean zoomIn = false;
    private IconScaleManager iconScaleManager = null;

    public ZoomListener(boolean zoom, IconScaleManager renderer) {
        zoomIn = zoom;
        iconScaleManager = renderer;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        iconScaleManager.scaleButton(zoomIn);
    }
}

2) ActionListener::actionPerformed()調用ScaleManagerscale method

@Override
public void actionPerformed(ActionEvent e) {
    iconScaleManager.scaleButton(zoomIn);
}

3) ScaleManager方法更改並更新ThumbnailFileChooser's Jlist的單元格(該列表是ScaleManager的屬性)

public class IconScaleManager {     
    static final int[] iconScales = new int[]{ 16, 32, 64, 128, 256, 512, 1024, 2048 };

    private int scaleIndex = 4;
    private JList fileList = null;

    public IconScaleManager(JList list) {
        fileList = list;
        setFixedCellDimension();
    }

    public void scaleButton(boolean zoomIn) {
        if (zoomIn && scaleIndex < iconScales.length - 1) {
            scaleIndex++;

            setFixedCellDimension();
        } else if (!zoomIn && 0 < scaleIndex) {
            scaleIndex--;

            setFixedCellDimension();
        }
    }

    private void setFixedCellDimension() {
        fileList.setFixedCellWidth(iconScales[scaleIndex]);
        fileList.setFixedCellHeight(iconScales[scaleIndex]);
    }
}

謝謝@ thanopi57的幫助。 我並沒有真正使用您提供的內容,但感謝您的支持。

另外,我必須確保它能正常工作,因為可能沒有針對所有JFileChooser的JList

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM