Изменение размера элементов файла JList в JFileChooser - PullRequest
0 голосов
/ 03 июля 2018

У меня есть JFileChooser. Я пытаюсь добавить функцию масштабирования для файлов JList.

Я хотел бы изменить коэффициент масштабирования имени файла и значка файла для каждого элемента списка.

Как мы можем этого достичь?

Ответы [ 2 ]

0 голосов
/ 25 июля 2018

В конце концов я понял, что масштабирование текста не нужно.

Чтобы получить миниатюру файлов изображений, я использовал код в , чтобы JFileChooser показывал миниатюры изображений - проверьте ответ BoffinbraiN.

Тогда для масштабирования:

1) добавить ActionListener к кнопкам ThumbnailFileChooser.

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() вызывает scale method из ScaleManager.

@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 за помощь. Я действительно не использовал то, что вы предоставили, но я ценю вашу поддержку.

Кроме того, я должен убедиться, что он работает, потому что не может быть JList для всех JFileChooser

0 голосов
/ 04 июля 2018

Ну, я нашел несколько уродливых ленивых хаков, чтобы сделать это. Это может быть не то, что вы хотите, но это хорошая отправная точка (и довольно простая):

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 для увеличения / уменьшения в качестве аксессуара . Прочитайте этот простой пример того, как это сделать.

Протестируйте этот код, и я жду комментариев ...

...