我有一个JFileChooser
。我正在尝试为文件JList
添加缩放功能。
我想为列表的每个元素更改文件名和文件图标的比例因子。
我们如何实现这一目标?
我应该像这里一样制作一个custom renderer
[JList自定义渲染器示例](http://www.codejava.net/java-se/swing/jlist-custom-renderer-example)
或更改列表Model
吗?
答案 0 :(得分:1)
好吧,我发现了一些丑陋的懒家伙。 它可能不仅是您想要的,而且是一个很好的起点(而且相当简单):
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
的可单独调整大小的单元格的答案here。
您也可以添加JFileChooser
的按钮来放大/缩小为accessory。阅读this简单示例以了解操作方法。
测试此代码,我正在等待评论...
答案 1 :(得分:1)
最后,我意识到不需要缩放文本。
要获取图像文件缩略图,我使用了making JFileChooser show image thumbnails中的代码-检查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的帮助。我并没有真正使用您提供的内容,但感谢您的支持。
此外,我必须确保它能正常工作,因为可能没有针对所有JFileChooser
的JList