テクスチャやらなんやら貼ればこれで勝てる(何に?
テクスチャやらなんやら貼ればこれで勝てる(何に?
いずれはフォトンマッピングとかやってみたい
バラードを作っているが先にポップスができるかも?とりあえず頑張る
ファイルがドロップされたときの処理でStream APIを使ってみた。filterでinstanceof使ってるけどこれFile以外のときあるのかな?まぁ、いいや。あとソースコードにコメントが一切ないのでコメント追加していきたい。
var list = (List<?>)transferable.getTransferData(DataFlavor.javaFileListFlavor); list.stream().filter(o -> o instanceof File).map(o -> (File)o).forEach(f -> {
import java.awt.Color; import java.awt.Desktop; import java.awt.Dimension; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JTable; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.SwingUtilities; import javax.swing.table.TableColumn; import javax.swing.table.AbstractTableModel; import javax.swing.filechooser.FileSystemView; import java.awt.event.MouseEvent; import java.awt.event.MouseAdapter; import java.awt.dnd.DropTarget; import java.awt.dnd.DnDConstants; import java.awt.dnd.DropTargetAdapter; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.datatransfer.DataFlavor; import java.util.Date; import java.util.List; import java.util.Arrays; import java.nio.file.Files; import java.text.SimpleDateFormat; import java.io.File; import java.io.IOException; import java.awt.datatransfer.UnsupportedFlavorException; public class JFiler{ private static final String[] FILE_SUFFIX = {"B", "KB", "MB", "GB", "TB", "PB"}; private static final int FILE_NAME_COLUMN = 0; private static final int FILE_MODIFY_COLUMN = 1; private static final int FILE_TYPE_COLUMN = 2; private static final int FILE_SIZE_COLUMN = 3; private static final String NAME_HEADER_TEXT = "名前"; private static final String MODIFY_HEADER_TEXT = "更新日時"; private static final String TYPE_HEADER_TEXT = "種類"; private static final String SIZE_HEADER_TEXT = "サイズ"; private static final Color HEADER_COLOR = new Color(0xee, 0xee, 0xFF); private static final Color CELL_SELECTED_COLOR = new Color(0xCC, 0xCC, 0xFF); private static final int COLUMN_COUNT = 4; public static void main(String... args){ SwingUtilities.invokeLater(JFiler::start); } private static void start(){ var frame = new JFrame(); var tab = new JTabbedPane(); var table = JFiler.createFileTable(tab, new File("./../")); table.setPreferredSize(new Dimension(600, 500)); tab.addTab(((FileModel)table.getModel()).getCurrentDirectoryName(), new JScrollPane(table)); frame.add(tab); frame.setVisible(true); frame.pack(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } private static void acceptFileDrop(JTable table){ var listener = new DropTargetAdapter(){ @Override public void dragOver(DropTargetDragEvent e){ if(e.isDataFlavorSupported(DataFlavor.javaFileListFlavor)){ e.acceptDrag(DnDConstants.ACTION_COPY); }else{ e.rejectDrag(); } } @Override public void drop(DropTargetDropEvent e){ if(e.isDataFlavorSupported(DataFlavor.javaFileListFlavor)){ e.acceptDrop(DnDConstants.ACTION_COPY); copyDropFiles(table, e); e.dropComplete(true); }else{ e.rejectDrop(); } } }; new DropTarget(table, DnDConstants.ACTION_COPY, listener, true); } private static void copyDropFiles(JTable table, DropTargetDropEvent e){ try{ var transferable = e.getTransferable(); var list = (List<?>)transferable.getTransferData(DataFlavor.javaFileListFlavor); list.stream().filter(o -> o instanceof File).map(o -> (File)o).forEach(f -> { var dstDir = ((FileModel)table.getModel()).getCurrentDirectory(); var dstFile = new File(dstDir, f.getName()); try{ Files.copy(f.toPath(), dstFile.toPath()); }catch(IOException exception){ JOptionPane.showMessageDialog(table, exception.getMessage()); exception.printStackTrace(); } }); }catch(UnsupportedFlavorException | IOException exception) { JOptionPane.showMessageDialog(table, exception.getMessage()); exception.printStackTrace(); } new Thread(() -> { var model = (FileModel)table.getModel(); model.setCurrentDirectory(model.getCurrentDirectory()); table.repaint(); }).run(); } private static JTable createFileTable(JTabbedPane tab, File dir){ var model = new FileModel(); var table = new JTable(model); table.setRowHeight(24); table.setShowGrid(false); table.setIntercellSpacing(new Dimension(0, 0)); var header = table.getTableHeader(); header.setDefaultRenderer((t, value, isSelected, hasFocus, row, column) -> { var label = new JLabel(value.toString()); label.setOpaque(true); label.setBackground(JFiler.HEADER_COLOR); return label; }); new Thread(() -> { model.setCurrentDirectory(dir); table.repaint(); }).run(); JFiler.setCellRenderer(table); JFiler.setMouseListener(tab, table); JFiler.acceptFileDrop(table); return table; } private static void setMouseListener(JTabbedPane tab, JTable table){ table.addMouseListener(new MouseAdapter(){ public void mouseClicked(MouseEvent e){ var model = (FileModel)table.getModel(); var row = table.rowAtPoint(e.getPoint()); var column = table.columnAtPoint(e.getPoint()); table.changeSelection(row, column, false, false); if(SwingUtilities.isLeftMouseButton(e)){ JFiler.leftClicked(e, table, model); }else if(SwingUtilities.isMiddleMouseButton(e)){ var file = (File)model.getValueAt(table.getSelectedRow(), 0); if(file.isDirectory()){ var newTable = JFiler.createFileTable(tab, file); var scroll = new JScrollPane(newTable); tab.addTab(((FileModel)newTable.getModel()).getCurrentDirectoryName(), scroll); tab.setSelectedComponent(scroll); } }else if(SwingUtilities.isRightMouseButton(e)){ } } }); } private static void setFileNameRenderer(TableColumn tc){ tc.setHeaderValue(JFiler.NAME_HEADER_TEXT); tc.setCellRenderer((t, value, isSelected, hasFocus, row, column) -> { var file = (File)value; var view = FileSystemView.getFileSystemView(); var icon = view.getSystemIcon(file); var label = new JLabel(file.getName(), icon, JLabel.LEFT); JFiler.setLabelBackground(label, isSelected, hasFocus); return label; }); } private static void setFileModifyRenderer(TableColumn tc){ tc.setHeaderValue(JFiler.MODIFY_HEADER_TEXT); tc.setCellRenderer((t, value, isSelected, hasFocus, row, column) -> { var file = (File)value; var date = new Date(file.lastModified()); var format = new SimpleDateFormat("yyyy/MM/dd HH:mm"); var label = new JLabel(format.format(date)); JFiler.setLabelBackground(label, isSelected, hasFocus); return label; }); } private static void setFileTypeRenderer(TableColumn tc){ tc.setHeaderValue(JFiler.TYPE_HEADER_TEXT); tc.setCellRenderer((t, value, isSelected, hasFocus, row, column) -> { var file = (File)value; var label = new JLabel(); if(file.isDirectory()){ label.setText("DIR"); }else{ try{ var path = file.getCanonicalPath(); var index = path.lastIndexOf("."); label.setText(path.substring(index + 1, path.length()).toUpperCase() + "ファイル"); }catch(IOException e){ var path = file.getName(); var index = path.lastIndexOf("."); label.setText(path.substring(index + 1, path.length()).toUpperCase() + "ファイル"); } } JFiler.setLabelBackground(label, isSelected, hasFocus); return label; }); } private static void setFileSizeRenderer(TableColumn tc){ tc.setHeaderValue(JFiler.SIZE_HEADER_TEXT); tc.setCellRenderer((t, value, isSelected, hasFocus, row, column) -> { var file = (File)value; var size = file.length(); var label = new JLabel(); var count = 0; while(size > 2048){ size /= 1024; count++; } if(!file.isDirectory()){ label.setText("" + size + JFiler.FILE_SUFFIX[count]); } JFiler.setLabelBackground(label, isSelected, hasFocus); return label; }); } private static void setLabelBackground(JLabel label, boolean isSelected, boolean hasFocus){ if(isSelected){ label.setOpaque(true); label.setBackground(JFiler.CELL_SELECTED_COLOR); } } private static void setCellRenderer(JTable table){ var columnModel = table.getColumnModel(); JFiler.setFileNameRenderer(columnModel.getColumn(JFiler.FILE_NAME_COLUMN)); JFiler.setFileModifyRenderer(columnModel.getColumn(JFiler.FILE_MODIFY_COLUMN)); JFiler.setFileTypeRenderer(columnModel.getColumn(JFiler.FILE_TYPE_COLUMN)); JFiler.setFileSizeRenderer(columnModel.getColumn(JFiler.FILE_SIZE_COLUMN)); } private static void leftClicked(MouseEvent e, JTable table, FileModel model){ if(e.getClickCount() == 2){ var file = (File)model.getValueAt(table.getSelectedRow(), 0); if(file.isDirectory()){ new Thread(() -> { model.setCurrentDirectory(file); table.repaint(); }).run(); }else{ try{ Desktop.getDesktop().open(file); }catch(IOException exception){ JOptionPane.showMessageDialog(table, exception.getMessage()); exception.printStackTrace(); } } } } private static class FileModel extends AbstractTableModel{ private File dir; private File[] children; public String getCurrentDirectoryName(){ try{ var path = dir.getCanonicalPath(); var index = path.lastIndexOf(File.separator); return path.substring(index + 1, path.length()); }catch(IOException e){ return dir.getName(); } } public File getCurrentDirectory(){ return dir; } public void setCurrentDirectory(File dir){ this.dir = dir; this.children = dir.listFiles(); Arrays.sort(this.children, (f1, f2) -> { if(f1.isDirectory() && !f2.isDirectory()){ return -1; }else if(!f1.isDirectory() && f2.isDirectory()){ return 1; }else{ return f1.getName().compareTo(f2.getName()); } }); } @Override public int getRowCount(){ return children.length; } @Override public int getColumnCount(){ return JFiler.COLUMN_COUNT; } @Override public Object getValueAt(int row, int column){ return children[row]; } } }
このブログももうすぐ4000エントリ…ここまで長かったがこれからも長くなる予定。頑張るぞ
1つのファイルだけでプログラミングしているが大丈夫か?になってきたのでそろそろ分割を考える。
あとはRowSorterを使ってみようかと思ったけど挙動がよくわからなかったのでJTableHeader(というかTableCellRenderer)を自前で用意してごにょごにょしてみようかと…
import java.awt.Color; import java.awt.Desktop; import java.awt.Dimension; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JTable; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.SwingUtilities; import javax.swing.table.TableColumn; import javax.swing.table.AbstractTableModel; import javax.swing.filechooser.FileSystemView; import java.awt.event.MouseEvent; import java.awt.event.MouseAdapter; import java.util.Date; import java.util.Arrays; import java.text.SimpleDateFormat; import java.io.File; import java.io.IOException; public class JFiler{ private static final String[] FILE_SUFFIX = {"B", "KB", "MB", "GB", "TB", "PB"}; private static final int FILE_NAME_COLUMN = 0; private static final int FILE_MODIFY_COLUMN = 1; private static final int FILE_TYPE_COLUMN = 2; private static final int FILE_SIZE_COLUMN = 3; private static final String NAME_HEADER_TEXT = "名前"; private static final String MODIFY_HEADER_TEXT = "更新日時"; private static final String TYPE_HEADER_TEXT = "種類"; private static final String SIZE_HEADER_TEXT = "サイズ"; private static final Color HEADER_COLOR = new Color(0xee, 0xee, 0xFF); private static final Color CELL_SELECTED_COLOR = new Color(0xCC, 0xCC, 0xFF); public static void main(String... args){ SwingUtilities.invokeLater(JFiler::start); } private static void start(){ var frame = new JFrame(); var tab = new JTabbedPane(); var table = JFiler.createFileTable(tab, new File("./../")); table.setPreferredSize(new Dimension(600, 500)); tab.addTab(((FileModel)table.getModel()).getCurrentDirectoryName(), new JScrollPane(table)); frame.add(tab); frame.setVisible(true); frame.pack(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } private static JTable createFileTable(JTabbedPane tab, File dir){ var model = new FileModel(); var table = new JTable(model); table.setRowHeight(24); table.setShowGrid(false); table.setIntercellSpacing(new Dimension(0, 0)); new Thread(() -> { model.setCurrentDirectory(dir); table.repaint(); }).run(); var header = table.getTableHeader(); header.setDefaultRenderer((t, value, isSelected, hasFocus, row, column) -> { var label = new JLabel(value.toString()); label.setOpaque(true); label.setBackground(JFiler.HEADER_COLOR); return label; }); JFiler.setCellRenderer(table); JFiler.setMouseListener(tab, table); return table; } private static void setMouseListener(JTabbedPane tab, JTable table){ table.addMouseListener(new MouseAdapter(){ public void mouseClicked(MouseEvent e){ var model = (FileModel)table.getModel(); var row = table.rowAtPoint(e.getPoint()); var column = table.columnAtPoint(e.getPoint()); table.changeSelection(row, column, false, false); if(SwingUtilities.isLeftMouseButton(e)){ JFiler.leftClicked(e, table, model); }else if(SwingUtilities.isMiddleMouseButton(e)){ var file = (File)model.getValueAt(table.getSelectedRow(), 0); if(file.isDirectory()){ var newTable = JFiler.createFileTable(tab, file); var scroll = new JScrollPane(newTable); tab.addTab(((FileModel)newTable.getModel()).getCurrentDirectoryName(), scroll); tab.setSelectedComponent(scroll); } } } }); } private static void setFileNameRenderer(TableColumn tc){ tc.setHeaderValue(JFiler.NAME_HEADER_TEXT); tc.setCellRenderer((t, value, isSelected, hasFocus, row, column) -> { var file = (File)value; var view = FileSystemView.getFileSystemView(); var icon = view.getSystemIcon(file); var label = new JLabel(file.getName(), icon, JLabel.LEFT); JFiler.setLabelBackground(label, isSelected, hasFocus); return label; }); } private static void setFileModifyRenderer(TableColumn tc){ tc.setHeaderValue(JFiler.MODIFY_HEADER_TEXT); tc.setCellRenderer((t, value, isSelected, hasFocus, row, column) -> { var file = (File)value; var date = new Date(file.lastModified()); var format = new SimpleDateFormat("yyyy/MM/dd HH:mm"); var label = new JLabel(format.format(date)); JFiler.setLabelBackground(label, isSelected, hasFocus); return label; }); } private static void setFileTypeRenderer(TableColumn tc){ tc.setHeaderValue(JFiler.TYPE_HEADER_TEXT); tc.setCellRenderer((t, value, isSelected, hasFocus, row, column) -> { var file = (File)value; var label = new JLabel(); if(file.isDirectory()){ label.setText("DIR"); }else{ try{ var path = file.getCanonicalPath(); var index = path.lastIndexOf("."); label.setText(path.substring(index + 1, path.length()).toUpperCase() + "ファイル"); }catch(IOException e){ var path = file.getName(); var index = path.lastIndexOf("."); label.setText(path.substring(index + 1, path.length()).toUpperCase() + "ファイル"); } } JFiler.setLabelBackground(label, isSelected, hasFocus); return label; }); } private static void setFileSizeRenderer(TableColumn tc){ tc.setHeaderValue(JFiler.SIZE_HEADER_TEXT); tc.setCellRenderer((t, value, isSelected, hasFocus, row, column) -> { var file = (File)value; var size = file.length(); var label = new JLabel(); var count = 0; while(size > 2048){ size /= 1024; count++; } if(!file.isDirectory()){ label.setText("" + size + JFiler.FILE_SUFFIX[count]); } JFiler.setLabelBackground(label, isSelected, hasFocus); return label; }); } private static void setLabelBackground(JLabel label, boolean isSelected, boolean hasFocus){ if(isSelected){ label.setOpaque(true); label.setBackground(JFiler.CELL_SELECTED_COLOR); } } private static void setCellRenderer(JTable table){ var columnModel = table.getColumnModel(); JFiler.setFileNameRenderer(columnModel.getColumn(JFiler.FILE_NAME_COLUMN)); JFiler.setFileModifyRenderer(columnModel.getColumn(JFiler.FILE_MODIFY_COLUMN)); JFiler.setFileTypeRenderer(columnModel.getColumn(JFiler.FILE_TYPE_COLUMN)); JFiler.setFileSizeRenderer(columnModel.getColumn(JFiler.FILE_SIZE_COLUMN)); } private static void leftClicked(MouseEvent e, JTable table, FileModel model){ if(e.getClickCount() == 2){ var file = (File)model.getValueAt(table.getSelectedRow(), 0); if(file.isDirectory()){ new Thread(() -> { model.setCurrentDirectory(file); table.repaint(); }).run(); }else{ try{ Desktop.getDesktop().open(file); }catch(IOException exception){ JOptionPane.showConfirmDialog(table, exception.getMessage()); } } } } private static class FileModel extends AbstractTableModel{ private File dir; private File[] children; public String getCurrentDirectoryName(){ try{ var path = dir.getCanonicalPath(); var index = path.lastIndexOf(File.separator); return path.substring(index + 1, path.length()); }catch(IOException e){ return dir.getName(); } } public void setCurrentDirectory(File dir){ this.dir = dir; this.children = dir.listFiles(); Arrays.sort(this.children, (f1, f2) -> { if(f1.isDirectory() && !f2.isDirectory()){ return -1; }else if(!f1.isDirectory() && f2.isDirectory()){ return 1; }else{ return f1.getName().compareTo(f2.getName()); } }); } @Override public int getRowCount(){ return children.length; } @Override public int getColumnCount(){ return 4; } @Override public Object getValueAt(int row, int column){ return children[row]; } } }
TableCellRendererの設定部分が長くなってきたのでメソッドをわけてみた。
JLabelの背景設定部分が共通だし、他にもJLabelの設定が増えるかもしれないので、それ用のメソッドを作っておこう。
だいぶプログラミング力が落ちていると実感しながら作っている
private static void setFileNameRenderer(TableColumn tc){ tc.setHeaderValue("名前"); tc.setCellRenderer((t, value, isSelected, hasFocus, row, column) -> { var file = (File)value; var view = FileSystemView.getFileSystemView(); var icon = view.getSystemIcon(file); var label = new JLabel(file.getName(), icon, JLabel.LEFT); if(isSelected){ label.setOpaque(true); label.setBackground(new Color(0xCC, 0xCC, 0xFF)); } return label; }); } private static void setFileModifyRenderer(TableColumn tc){ tc.setHeaderValue("更新日時"); tc.setCellRenderer((t, value, isSelected, hasFocus, row, column) -> { var file = (File)value; var date = new Date(file.lastModified()); var format = new SimpleDateFormat("yyyy/MM/dd HH:mm"); var label = new JLabel(format.format(date)); if(isSelected){ label.setOpaque(true); label.setBackground(new Color(0xCC, 0xCC, 0xFF)); } return label; }); } private static void setFileTypeRenderer(TableColumn tc){ tc.setHeaderValue("種類"); tc.setCellRenderer((t, value, isSelected, hasFocus, row, column) -> { var file = (File)value; var label = new JLabel(); if(file.isDirectory()){ label.setText("DIR"); }else{ try{ var path = file.getCanonicalPath(); var index = path.lastIndexOf("."); label.setText(path.substring(index + 1, path.length()).toUpperCase() + "ファイル"); }catch(IOException e){ var path = file.getName(); var index = path.lastIndexOf("."); label.setText(path.substring(index + 1, path.length()).toUpperCase() + "ファイル"); } } if(isSelected){ label.setOpaque(true); label.setBackground(new Color(0xCC, 0xCC, 0xFF)); } return label; }); } private static void setFileSizeRenderer(TableColumn tc){ tc.setHeaderValue("サイズ"); tc.setCellRenderer((t, value, isSelected, hasFocus, row, column) -> { var file = (File)value; var size = file.length(); var label = new JLabel(); var count = 0; while(size > 2048){ size /= 1024; count++; } if(!file.isDirectory()){ label.setText("" + size + JFiler.FILE_SUFFIX[count]); } if(isSelected){ label.setOpaque(true); label.setBackground(new Color(0xCC, 0xCC, 0xFF)); } return label; }); } private static void setCellRenderer(JTable table){ var columnModel = table.getColumnModel(); JFiler.setFileNameRenderer(columnModel.getColumn(JFiler.FILE_NAME_COLUMN)); JFiler.setFileModifyRenderer(columnModel.getColumn(JFiler.FILE_MODIFY_COLUMN)); JFiler.setFileTypeRenderer(columnModel.getColumn(JFiler.FILE_TYPE_COLUMN)); JFiler.setFileSizeRenderer(columnModel.getColumn(JFiler.FILE_SIZE_COLUMN)); }