java 簡易csvエディタ風?? ファイルドロップテスト( 4 )
■ csvクラス修正
■ JTextArea のキーアクション制御 エンターキー無効化(1)
■ JTextArea のキーアクション制御 エンターキー無効化(2)
前回作成した csv ファイルをJTableクラスを利用してテーブルへ書き出すプログラムへ
テキストエリア内での編集機能と保存機能を追加。
テキストエリア内の編集は、UndoManagerの実装例を参考にさせて頂きました。
csv ファイルをテキストエリアへドロップすると、csv データを配列へ格納、配列からテーブルを生成。
テーブルのセルクリック、またはJTableクラスに設定してあるキーアクションでセルの内容を下段テキストエリアへ出力。
出力されたテキストエリア内での編集は、元の戻す、やり直し、コピー、切り取り、貼り付け、全て選択などの編集ができます。
テキストエリアフォーカスでデータ編集、enter キーでフォーカスがテキストエリアからテーブルへ移動します。
テキストエリア内で改行をする場合は、ctrl + enter キーです。
フォーカスがテキストエリアからテーブルへ移動するときテキストが ”カックンっ!!” となります。
enter キーの挙動をうまく制御できてません。
カンマ、ダブルクォーテーションを入力した場合も未対応。
その他も、、、。
編集したデータを保存する場合は保存ボタンを押してください。
java ファイルと同じ階層へ入力ファイルと同名で csv ファイルを書き出します。( エンコードは utf-8 です。 )
csvは、ダブルクオーテーションのカンマ区切り、セル数が一定のファイルに一応、対応しています??
CSV クラス → java StringBufferクラスの利用 csvファイルの読み込みと出力テスト
■ プログラムの流れ
- 拡張子が csv のファイルを下段にあるテキストエリアへドロップする。
- 出力データが文字化けする場合はラジオボタンのチェック変更。
- ドロップすると csv ファイルを配列へ格納し、配列からJTableの生成。
- JTable のセルをクリックするとセルの内容が下段のテキストエリアへ出力。
- JTableにフォーカスがある場合は、キーアクションでセルの移動、セルの内容出力。
- テキストエリアで csv データの編集。( 改行は enter + ctrl キー )
- 保存ボタンで java ファイルと同じ階層へ csv ファイル出力
■ プログラムの実行と手順
- javaファイルをコンパイルする ( javac -encoding utf-8 dropTest.java )
- javaの実行 ( java dropTest )
- 作成されたJFrameないのテキストエリアへ csv ファイルをドロップする。( カンマ切りの csv ファイル )
- csv データの編集
- 保存ボタンで csv ファイル出力
■ 実行結果 ( 1 )

■ 実行結果 ( 2 )

■ 実行結果 ( 3 )

■ dropTest.java
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import javax.swing.border.LineBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.Document;
import javax.swing.undo.UndoManager;
class dropTest extends JFrame
{
JRadioButton[] radioButton;
JPopupMenu popUpMenu=null;
JPanel tableArea;
JTable table;
CSV csvObj;
String data[][];
JLabel rowArea;
JLabel colArea;
JPanel myTextPanel;
MyTextArea[][] textList;
MyTextArea target;
String fileName;
static dropTest main;
private class MyTextArea extends JTextArea
{
protected UndoManager undoManager=new UndoManager();
MyTextArea(String str) throws Exception
{
setPreferredSize(new Dimension(1000,1000));
setBorder(new LineBorder(Color.white,8,false));
setText(str);
setEditable(false);
setDisabledTextColor(Color.gray);
DropTarget dropTarget=new DropTarget();
setDropTarget(dropTarget);
dropTarget.addDropTargetListener(new DropTargetListener()
{
public void drop(DropTargetDropEvent evt)
{
evt.acceptDrop(DnDConstants.ACTION_COPY);
try
{
Transferable transferble=evt.getTransferable();
if(transferble.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
{
List list=(List)transferble.getTransferData(DataFlavor.javaFileListFlavor);
if(list.size()==1)
{
File file=(File)list.get(0);
fileName=file.getAbsolutePath();
String regex=".csv$";
Pattern p=Pattern.compile(regex);
Matcher m=p.matcher(fileName);
if(m.find()&&fileName.endsWith(".csv")&&file.canRead())
{
String encoding=(radioButton[0].isSelected())? "utf-8":"JISAutoDetect";
System.out.println(fileName+" name");
csvObj=new CSV();
data=csvObj.fgetcsv(fileName,encoding);
tableArea.removeAll();
validate();
table=new JTable(csvObj.setData(data,1),data[0]);
table.getTableHeader().setReorderingAllowed(false);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.setDefaultEditor(Object.class,null);
table.setColumnSelectionAllowed(true);
table.setRowSelectionAllowed(true);
table.setSelectionBackground(Color.red);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.addMouseListener(new MouseAdapter()
{
public void mouseReleased(MouseEvent e)
{
try
{
JTable tb=(JTable)(e.getSource());
int row=tb.getSelectedRow();
int col=tb.getSelectedColumn();
tb.repaint();
target.setVisible(false);
target=textList[row][col];
target.setText(data[row+1][col]);
target.setEditable(true);
target.setVisible(true);
target.setCaretPosition(0);
rowArea.setText(row+" ");
colArea.setText(col+" ");
}
catch(NullPointerException error){}
catch(ArrayIndexOutOfBoundsException error){}
}
});
table.addKeyListener(new KeyAdapter()
{
public void keyReleased(KeyEvent e)
{
try
{
JTable tb=(JTable)(e.getSource());
int row=tb.getSelectedRow();
int col=tb.getSelectedColumn();
tb.repaint();
target.setVisible(false);
target=textList[row][col];
target.setText(data[row+1][col]);
target.setEditable(true);
target.setVisible(true);
target.setCaretPosition(0);
rowArea.setText(row+" ");
colArea.setText(col+" ");
}
catch(NullPointerException error){}
catch(ArrayIndexOutOfBoundsException error){}
}
});
JScrollPane tableScroll=new JScrollPane(table);
tableArea.add(tableScroll);
tableArea.validate();
table.requestFocus();
myTextPanel.removeAll();
textList=new MyTextArea[data.length][data[0].length];
for(int i=1;i<data.length;i++)
{
for(int j=0;j<data[i].length;j++)
{
boolean flg=(i==1&&j==0)?true:false;
try
{
MyTextArea text=new MyTextArea(data[i][j]);
textList[i-1][j]=text;
text.setVisible(flg);
myTextPanel.add(text);
}catch(Exception e){ System.out.println("error"); }
}
}
target=textList[0][0];
myTextPanel.validate();
}
}
}
}
catch(UnsupportedFlavorException dex){}
catch(IOException dex){}
}
public void dropActionChanged(DropTargetDragEvent e){}
public void dragOver(DropTargetDragEvent e){}
public void dragEnter(DropTargetDragEvent e){}
public void dragExit(DropTargetEvent e) {}
});
Document doc=getDocument();
doc.addUndoableEditListener(new UndoableEditListener()
{
public void undoableEditHappened(UndoableEditEvent e)
{
undoManager.addEdit(e.getEdit());
}
});
getDocument().addDocumentListener(new DocumentListener()
{
public void insertUpdate(DocumentEvent e){}
public void removeUpdate(DocumentEvent e){}
public void changedUpdate(DocumentEvent e) {}
});
addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
if(javax.swing.SwingUtilities.isRightMouseButton(e))
{
if(popUpMenu==null)
{
Font font=new Font("Meiryo",Font.PLAIN,12);
popUpMenu=new JPopupMenu();
popUpMenu.addSeparator();
JMenuItem menuItem=new JMenuItem("元に戻す");
menuItem.setFont(font);
menuItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
if(undoManager.canUndo()){ undoManager.undo(); }
}
});
popUpMenu.add(menuItem);
popUpMenu.addSeparator();
menuItem=new JMenuItem("やり直し");
menuItem.setFont(font);
menuItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
if(undoManager.canRedo()){ undoManager.redo(); }
}
});
popUpMenu.add(menuItem);
popUpMenu.addSeparator();
popUpMenu.addSeparator();
JComponent component=(JComponent)e.getComponent();
ActionMap actionMap=component.getActionMap();
Action action=actionMap.get(DefaultEditorKit.copyAction);
menuItem=popUpMenu.add(action);
menuItem.setText("コピー");
menuItem.setFont(font);
popUpMenu.addSeparator();
action=actionMap.get(DefaultEditorKit.pasteAction);
menuItem=popUpMenu.add(action);
menuItem.setText("貼り付け");
menuItem.setFont(font);
popUpMenu.addSeparator();
action=actionMap.get(DefaultEditorKit.cutAction);
menuItem=popUpMenu.add(action);
menuItem.setText("切り取り");
menuItem.setFont(font);
popUpMenu.addSeparator();
action=actionMap.get(DefaultEditorKit.selectAllAction);
menuItem=popUpMenu.add(action);
menuItem.setText("すべて選択");
menuItem.setFont(font);
popUpMenu.addSeparator();
}
popUpMenu.show(e.getComponent(),e.getX()-4,e.getY()-6);
}
}
});
addKeyListener(new KeyAdapter()
{
public void keyTyped(KeyEvent e){}
public void keyPressed(KeyEvent e)
{
switch (e.getKeyCode())
{
case KeyEvent.VK_Z:
if (e.isControlDown()&&undoManager.canUndo())
{
undoManager.undo();
e.consume();
}
break;
case KeyEvent.VK_Y:
if (e.isControlDown()&&undoManager.canRedo())
{
undoManager.redo();
e.consume();
}
break;
}
}
public void keyReleased(KeyEvent e)
{
int mod = e.getModifiersEx();
int caretPosition=getCaretPosition();
if(((mod & InputEvent.CTRL_DOWN_MASK)!=0)&&(e.getKeyCode()==KeyEvent.VK_ENTER))
{
int row=table.getSelectedRow();
int col=table.getSelectedColumn();
insert("\n",caretPosition);
data[row+1][col]=getText();
}
else if((e.getKeyCode()==KeyEvent.VK_ENTER))
{
try
{
String str=getText().substring(caretPosition-1,caretPosition);
if(str.equals("\n")||str.equals("\r\n"))
{
replaceRange("",caretPosition-1,caretPosition);
table.requestFocus();
}
}
catch(StringIndexOutOfBoundsException ie)
{
replaceRange("",0,1);
}
//table.requestFocus();
}
else
{
int row=table.getSelectedRow();
int col=table.getSelectedColumn();
data[row+1][col]=getText();
}
}
});
}
}
dropTest() throws Exception
{
setTitle("Drop Test");
Dimension dimension=Toolkit.getDefaultToolkit().getScreenSize();
int width=(int)dimension.getWidth();
int height=(int)dimension.getHeight();
setBounds((width-600)/2,(height-500)/2,600,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel menuArea=new JPanel();
menuArea.setLayout(new BoxLayout(menuArea,BoxLayout.LINE_AXIS));
JPanel menu=new JPanel();
menu.setLayout(new FlowLayout(FlowLayout.RIGHT));
JLabel label=new JLabel("行:");
label.setFont(new Font("Meiyo",Font.PLAIN,12));
menu.add(label);
rowArea=new JLabel("0 ",JLabel.RIGHT);
rowArea.setPreferredSize(new Dimension(70,18));
rowArea.setBorder(new LineBorder(Color.gray,1,false));
menu.add(rowArea);
menu.add(Box.createHorizontalStrut(10));
label=new JLabel("列:");
label.setFont(new Font("Meiyo",Font.PLAIN,12));
menu.add(label);
colArea=new JLabel("0 ",JLabel.RIGHT);
colArea.setBorder(new LineBorder(Color.gray,1,false));
colArea.setPreferredSize(new Dimension(70,18));
menu.add(colArea);
menu.add(Box.createHorizontalStrut(20));
ButtonGroup bg=new ButtonGroup();
radioButton=new JRadioButton[2];
radioButton[0]=new JRadioButton("UTF-8");
radioButton[0].setFont(new Font("Meiryo",Font.PLAIN,12));
bg.add(radioButton[0]);
radioButton[0].setSelected(true);
radioButton[1]=new JRadioButton("OTHER");
radioButton[1].setFont(new Font("Meiryo",Font.PLAIN,12));
bg.add(radioButton[1]);
label=new JLabel("エンコード選択:");
label.setFont(new Font("Meiryo",Font.PLAIN,12));
menu.add(label);
menu.add(radioButton[0]);
menu.add(radioButton[1]);
menu.add(Box.createHorizontalStrut(10));
JButton seve=new JButton("保存");
seve.setFont(new Font("Meiryo",Font.PLAIN,12));
menu.add(seve);
seve.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
try
{
csvObj.setData(data);
File file=new File(fileName);
csvObj.write(file.getName());
JLabel label=new JLabel(new File(".").getAbsolutePath().replaceAll("\\.$","")+file.getName()+"へ保存しました。");
label.setFont(new Font("Meiryo",Font.PLAIN,12));
label.setHorizontalAlignment(JLabel.CENTER);
JOptionPane.showMessageDialog(main,label);
}
catch(FileNotFoundException error){}
catch(IOException error){}
catch(NullPointerException error){}
}
});
menuArea.add(menu);
tableArea=new JPanel();
tableArea.setLayout(new BoxLayout(tableArea,BoxLayout.PAGE_AXIS));
label=new JLabel("テーブルエリア");
label.setFont(new Font("Meiryo",Font.PLAIN,12));
tableArea.add(label);
myTextPanel=new JPanel();
myTextPanel.add(new MyTextArea("カンマ区切りのcsvファイルをドロップしてください。"));
JScrollPane textScroll=new JScrollPane(myTextPanel);
textScroll.getVerticalScrollBar().setUnitIncrement(10);
JPanel content=new JPanel();
content.setLayout(new BoxLayout(content,BoxLayout.PAGE_AXIS));
content.add(menuArea);
content.add(textScroll);
JSplitPane splitPane=new JSplitPane(JSplitPane.VERTICAL_SPLIT,tableArea,content);
splitPane.setDividerLocation(230);
add(splitPane,BorderLayout.CENTER);
//pack();
}
public static void main(String args[]) throws Exception
{
main=new dropTest();
main.setVisible(true);
}
}
■ CSV.java
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class CSV
{
private int getQuotLength(String str,int index)
{
int result=0;
if(index==0)
{
for(int i=0;i<str.length();i++)
{
try
{
if(str.substring(i,i+1).equals("\"")){ result++; }else{ break;}
}
catch(StringIndexOutOfBoundsException e){ System.out.println(e); }
}
}
else
{
for(int i=str.length();i>0;i--)
{
if(str.substring(i-1,i).equals("\n")){ continue; }
try
{
if(str.substring(i-1,i).equals("\"")){ result++; }else{ break; }
}
catch(StringIndexOutOfBoundsException e){ System.out.println(e); }
}
}
return result;
}
public String[][] htmlSpecialChars(String[][] str )
{
String[][] result=new String[str.length][str[0].length];
String regex0="[ ]+\n$";
Pattern p0=Pattern.compile(regex0);
String regex1="\\&(?!amp;|quot;|gt;|lt;)";
Pattern p1 = Pattern.compile(regex1);
String regex2 = "<";
Pattern p2=Pattern.compile(regex2);
String regex3=">";
Pattern p3=Pattern.compile(regex3);
String regex4="\"";
Pattern p4=Pattern.compile(regex4);
for(int i=0;i<str.length;i++)
{
for(int j=0;j<str[i].length;j++)
{
Matcher m0=p0.matcher(str[i][j]);
str[i][j]=m0.replaceAll("\n");
Matcher m1=p1.matcher(str[i][j]);
str[i][j]=m1.replaceAll("&");
Matcher m2=p2.matcher(str[i][j]);
str[i][j]=m2.replaceAll("<");
Matcher m3=p3.matcher(str[i][j]);
str[i][j]=m3.replaceAll(">");
Matcher m4=p4.matcher(str[i][j]);
str[i][j]=m4.replaceAll(""");
}
}
return str;
}
final void setData(String[][] data){ csv=null; csv=data; }
final String[][] setData(String[][] data,Integer index)
{
String[][] newData=new String[data.length-1][data[0].length];
System.arraycopy(data,index,newData,0,data.length-1);
return newData;
}
final String[][] join(String[][] d1,String[][] d2)
{
String[][] data=new String[d1.length+d2.length][d1[0].length];
System.arraycopy(d1,0,data,0,d1.length);
System.arraycopy(d2,0,data,d1.length,d2.length);
return data;
}
final void write(String fileName) throws FileNotFoundException, IOException
{
try(BufferedWriter output=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName),"utf-8")))
{
StringBuffer result=new StringBuffer();
for(int i=0;i<csv.length;i++)
{
for(int j=0;j<csv[i].length;j++)
{
String str=(csv[i][j]==null)? "": csv[i][j];
if(str.indexOf("\"")==0&&str.lastIndexOf("\"")==str.length()-1)
{
str=str.substring(1,str.length()-1);
}
String comma="\",\"";
String quot=(j==0)?"\"":"";
if(j==(csv[i].length-1)){ comma="\"\n"; }
result.append(quot);
result.append(str);
result.append(comma);
}
}
output.write(result.toString().trim());
output.close();
}
}
private String[][] csv;
final String[][] fgetcsv(String fileName) throws FileNotFoundException, IOException
{
csv=null;
try(BufferedReader input=new BufferedReader(new InputStreamReader(new FileInputStream(fileName),"JISAutoDetect")))
{
ArrayList<ArrayList> rows=new ArrayList<>();
ArrayList<String> cols=new ArrayList<>();
String str="";
String line;
int rowsIndex=0;
int colsIndex=0;
int colsMax=0;
boolean group=false;
int cnt=0;
while((line=input.readLine())!=null)
{
line=line.replaceAll("[ ]*[,][ ]*",",");
line=line+(String)"\n";
String[] parts=line.split(",");
for(int i=0;i<parts.length;i++)
{
int quotIn=(Integer)getQuotLength(parts[i],0)%2;
int quotOut=(Integer)getQuotLength(parts[i],-1)%2;
if(quotIn==1){ group=true; }
if(quotIn==1&"Out==1){ group=false; }
if("\"\n".equals(parts[i])){ group=true; cnt++; }
if("\"\n".equals(parts[i])&&cnt%2==0){ group=false; }
if("\"".equals(parts[i])&&group==true){ group=false; }
if(quotIn==1&"Out==0){ group=true; cnt++; }
if(quotIn==0&"Out==1){ group=false; }
parts[i]=("".equals(parts[i])||parts.length!=1)? parts[i]+"," : parts[i];
parts[i]=parts[i].replaceAll("\n,$","\n");
str+=parts[i];
if(group==false)
{
str=str.replaceAll(",$","");
str=str.trim();
cols.add(colsIndex,str);
str="";
colsIndex++;
}
if(group==false&&parts[i].indexOf((String)"\n")!=-1)
{
rows.add(rowsIndex,cols);
cols=new ArrayList<>();
colsMax=(colsMax<colsIndex)? colsIndex:colsMax;
colsIndex=0;
rowsIndex++;
}
}
}
csv=new String[rows.size()][colsMax];
for(int i=0;i<rows.size();i++)
{
for(int j=0;j<rows.get(i).size();j++)
{
csv[i][j]="";
String result=(String)rows.get(i).get(j);
result=result.trim();
rows.get(i).set(j,result);
if(result.indexOf("\"")==0&&result.lastIndexOf("\"")==result.length()-1)
{
result=result.substring(1,result.length()-1);
}
csv[i][j]=result;
}
}
input.close();
}
return csv;
}
final String[][] fgetcsv(String fileName,String encode) throws FileNotFoundException, IOException
{
csv=null;
try(BufferedReader input=new BufferedReader(new InputStreamReader(new FileInputStream(fileName),encode)))
{
ArrayList<ArrayList> rows=new ArrayList<>();
ArrayList<String> cols=new ArrayList<>();
String str="";
String line;
int rowsIndex=0;
int colsIndex=0;
int colsMax=0;
boolean group=false;
int cnt=0;
while((line=input.readLine())!=null)
{
line=line.replaceAll("[ ]*[,][ ]*",",");
line=line+(String)"\n";
String[] parts=line.split(",");
for(int i=0;i<parts.length;i++)
{
int quotIn=(Integer)getQuotLength(parts[i],0)%2;
int quotOut=(Integer)getQuotLength(parts[i],-1)%2;
if(quotIn==1){ group=true; }
if(quotIn==1&"Out==1){ group=false; }
if("\"\n".equals(parts[i])){ group=true; cnt++; }
if("\"\n".equals(parts[i])&&cnt%2==0){ group=false; }
if("\"".equals(parts[i])&&group==true){ group=false; }
if(quotIn==1&"Out==0){ group=true; cnt++; }
if(quotIn==0&"Out==1){ group=false; }
parts[i]=("".equals(parts[i])||parts.length!=1)? parts[i]+"," : parts[i];
parts[i]=parts[i].replaceAll("\n,$","\n");
str+=parts[i];
if(group==false)
{
str=str.replaceAll(",$","");
str=str.trim();
cols.add(colsIndex,str);
str="";
colsIndex++;
}
if(group==false&&parts[i].indexOf((String)"\n")!=-1)
{
rows.add(rowsIndex,cols);
cols=new ArrayList<>();
colsMax=(colsMax<colsIndex)? colsIndex:colsMax;
colsIndex=0;
rowsIndex++;
}
}
}
csv=new String[rows.size()][colsMax];
for(int i=0;i<rows.size();i++)
{
for(int j=0;j<rows.get(i).size();j++)
{
csv[i][j]="";
String result=(String)rows.get(i).get(j);
result=result.trim();
rows.get(i).set(j,result);
if(result.indexOf("\"")==0&&result.lastIndexOf("\"")==result.length()-1)
{
result=result.substring(1,result.length()-1);
}
csv[i][j]=result;
}
}
input.close();
}
return csv;
}
}
java csvファイル読み込みとドロップイベントによるデータの受け渡し( 3 )
前回作成した
ドロップイベント
の読み込み拡張子( txt )を csv に変更。
CSVクラス → java StringBufferクラスの利用 csvファイルの読み込みと出力テスト
ファイルのドロップ動作は、前回と同じ。
拡張子が csv のファイルをテキストエリア内へドロップするとデータを配列に格納、配列からJTable作成。
前回のはテキストエリアへテキストを出力するだけだったけど、今回はJTableクラスを利用して、
csv データをテーブルへ出力するように変更。
文字化けする場合は、OTHER へチェックを入れる。
出力した、テーブルのセルをクリックすると下段のテキストエリアへセル内のデータが出力されます。
JTableクラスに最初から設定されているキーアクションで選択セル移動(tabキー、enterキー、shift + enterキーなど)、
テキストエリアの値の変更。
csvは、ダブルクオーテーションのカンマ区切り、セル数が一定のファイルに一応、対応しています??
■ プログラムの流れ
- 拡張子が csv のファイルを下段にあるテキストエリアへドロップする。
- 出力データが文字化けする場合はラジオボタンのチェック変更。
- ドロップすると csv ファイルを配列へ格納し、配列からJTableの生成。
- JTable のセルをクリックするとセルの内容が下段のテキストエリアへ出力。
- JTableにフォーカスがある場合は、キーアクションでセルの移動、セルの内容出力。
■ プログラムの実行と手順
- javaファイルをコンパイルする ( javac -encoding utf-8 dropTest.java )
- javaの実行 ( java dropTest )
- 作成されたJFrame内のテキストエリアへ csv ファイルをドロップする。( カンマ切りの csv ファイル )
■ 実行結果

■ dropTest.java
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import javax.swing.border.LineBorder;
class dropTest extends JFrame
{
JTextArea textArea;
JRadioButton[] radioButton;
JPopupMenu popUpMenu=null;
JPanel tableArea;
JTable table;
String data[][];
JLabel rowArea;
JLabel colArea;
dropTest() throws Exception
{
setTitle("Drop Test");
Dimension dimension=Toolkit.getDefaultToolkit().getScreenSize();
int width=(int)dimension.getWidth();
int height=(int)dimension.getHeight();
setBounds((width-600)/2,(height-500)/2,600,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel menu=new JPanel();
menu.setLayout(new FlowLayout(FlowLayout.RIGHT));
JLabel label=new JLabel("行:");
label.setFont(new Font("Meiyo",Font.PLAIN,12));
menu.add(label);
rowArea=new JLabel("0 ",JLabel.RIGHT);
rowArea.setPreferredSize(new Dimension(80,18));
rowArea.setBorder(new LineBorder(Color.gray,1,false));
menu.add(rowArea);
menu.add(Box.createHorizontalStrut(10));
label=new JLabel("列:");
label.setFont(new Font("Meiyo",Font.PLAIN,12));
menu.add(label);
colArea=new JLabel("0 ",JLabel.RIGHT);
colArea.setBorder(new LineBorder(Color.gray,1,false));
colArea.setPreferredSize(new Dimension(80,18));
menu.add(colArea);
menu.add(Box.createHorizontalStrut(20));
ButtonGroup bg=new ButtonGroup();
radioButton=new JRadioButton[2];
radioButton[0]=new JRadioButton("UTF-8");
radioButton[0].setFont(new Font("Meiryo",Font.PLAIN,12));
bg.add(radioButton[0]);
radioButton[0].setSelected(true);
radioButton[1]=new JRadioButton("OTHER");
radioButton[1].setFont(new Font("Meiryo",Font.PLAIN,12));
bg.add(radioButton[1]);
label=new JLabel("エンコード選択:");
label.setFont(new Font("Meiryo",Font.PLAIN,12));
menu.add(label);
menu.add(radioButton[0]);
menu.add(radioButton[1]);
textArea=new JTextArea(50,100);
textArea.setBorder(new LineBorder(Color.white,8,false));
textArea.setText("カンマ区切りのcsvファイルをドロップしてください。");
textArea.setEnabled(false);
textArea.setDisabledTextColor(Color.black);
DropTarget dropTarget=new DropTarget();
textArea.setDropTarget(dropTarget);
dropTarget.addDropTargetListener(new DropTargetListener()
{
public void drop(DropTargetDropEvent evt)
{
evt.acceptDrop(DnDConstants.ACTION_COPY);
try
{
Transferable transferble=evt.getTransferable();
if(transferble.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
{
List list=(List)transferble.getTransferData(DataFlavor.javaFileListFlavor);
if(list.size()==1)
{
File file=(File)list.get(0);
String path=file.getAbsolutePath();
String regex=".csv$";
Pattern p=Pattern.compile(regex);
Matcher m=p.matcher(path);
if(m.find()&&path.endsWith(".csv")&&file.canRead())
{
String encoding=(radioButton[0].isSelected())? "utf-8":"JISAutoDetect";
CSV csvObj=new CSV();
data=csvObj.fgetcsv(path,encoding);
tableArea.removeAll();
validate();
table=new JTable(csvObj.setData(data,1),data[0]);
table.getTableHeader().setReorderingAllowed(false);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.setDefaultEditor(Object.class,null);
table.setColumnSelectionAllowed(true);
table.setRowSelectionAllowed(true);
table.setSelectionBackground(Color.red);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.addMouseListener(new MouseAdapter()
{
public void mouseReleased(MouseEvent e)
{
try
{
JTable tb=(JTable)(e.getSource());
int row=tb.getSelectedRow();
int col=tb.getSelectedColumn();
tb.repaint();
textArea.setText(data[row+1][col]);
textArea.setCaretPosition(0);
rowArea.setText(row+" ");
colArea.setText(col+" ");
}
catch(NullPointerException error){}
catch(ArrayIndexOutOfBoundsException error){}
}
});
table.addKeyListener(new KeyAdapter()
{
public void keyReleased(KeyEvent e)
{
try
{
JTable tb=(JTable)(e.getSource());
int row=tb.getSelectedRow();
int col=tb.getSelectedColumn();
tb.repaint();
textArea.setText(data[row+1][col]);
textArea.setCaretPosition(0);
rowArea.setText(row+" ");
colArea.setText(col+" ");
}
catch(NullPointerException error){}
catch(ArrayIndexOutOfBoundsException error){}
}
});
JScrollPane tableScroll=new JScrollPane(table);
tableArea.add(tableScroll);
tableArea.validate();
textArea.setText(data[1][0]);
}
System.out.println(file.getAbsolutePath());
}
}
}
catch(UnsupportedFlavorException dex){}
catch(IOException dex){}
}
public void dropActionChanged(DropTargetDragEvent e){}
public void dragOver(DropTargetDragEvent e){}
public void dragEnter(DropTargetDragEvent e){}
public void dragExit(DropTargetEvent e) {}
});
tableArea=new JPanel();
tableArea.setLayout(new BoxLayout(tableArea,BoxLayout.PAGE_AXIS));
label=new JLabel("テーブルエリア");
label.setFont(new Font("Meiryo",Font.PLAIN,12));
tableArea.add(label);
JScrollPane textScroll=new JScrollPane(textArea);
JPanel content=new JPanel();
content.setLayout(new BoxLayout(content,BoxLayout.PAGE_AXIS));
content.add(menu);
content.add(textScroll);
JSplitPane splitPane=new JSplitPane(JSplitPane.VERTICAL_SPLIT,tableArea,content);
splitPane.setDividerLocation(230);
add(splitPane,BorderLayout.CENTER);
}
public static void main(String args[]) throws Exception
{
new dropTest().setVisible(true);
}
}
■ CSV.java
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CSV
{
private int getQuotLength(String str,int index)
{
int result=0;
if(index==0)
{
for(int i=0;i<str.length();i++)
{
try
{
if(str.substring(i,i+1).equals("\"")){ result++; }else{ break;}
}
catch(StringIndexOutOfBoundsException e){ System.out.println(e); }
}
}
else
{
for(int i=str.length();i>0;i--)
{
if(str.substring(i-1,i).equals("\n")){ continue; }
try
{
if(str.substring(i-1,i).equals("\"")){ result++; }else{ break; }
}
catch(StringIndexOutOfBoundsException e){ System.out.println(e); }
}
}
return result;
}
public String[][] htmlSpecialChars(String[][] str )
{
String[][] result=new String[str.length][str[0].length];
String regex0="[ ]+\n$";
Pattern p0=Pattern.compile(regex0);
String regex1="\\&(?!amp;|quot;|gt;|lt;)";
Pattern p1 = Pattern.compile(regex1);
String regex2 = "<";
Pattern p2=Pattern.compile(regex2);
String regex3=">";
Pattern p3=Pattern.compile(regex3);
String regex4="\"";
Pattern p4=Pattern.compile(regex4);
for(int i=0;i<str.length;i++)
{
for(int j=0;j<str[i].length;j++)
{
Matcher m0=p0.matcher(str[i][j]);
str[i][j]=m0.replaceAll("\n");
Matcher m1=p1.matcher(str[i][j]);
str[i][j]=m1.replaceAll("&");
Matcher m2=p2.matcher(str[i][j]);
str[i][j]=m2.replaceAll("<");
Matcher m3=p3.matcher(str[i][j]);
str[i][j]=m3.replaceAll(">");
Matcher m4=p4.matcher(str[i][j]);
str[i][j]=m4.replaceAll(""");
}
}
return str;
}
public void setData(String[][] data){ csv=null; csv=data; }
public String[][] setData(String[][] data,Integer index)
{
String[][] newData=new String[data.length-1][data[0].length];
System.arraycopy(data,index,newData,0,data.length-1);
return newData;
}
public String[][] join(String[][] d1,String[][] d2)
{
String[][] data=new String[d1.length+d2.length][d1[0].length];
System.arraycopy(d1,0,data,0,d1.length);
System.arraycopy(d2,0,data,d1.length,d2.length);
return data;
}
public void write(String fileName) throws FileNotFoundException, IOException
{
try(BufferedWriter output=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName),"utf-8")))
{
StringBuffer result=new StringBuffer();
for(int i=0;i<csv.length;i++)
{
for(int j=0;j<csv[i].length;j++)
{
String str=csv[i][j];
if(str.indexOf("\"")==0&&str.lastIndexOf("\"")==str.length()-1)
{
str=str.substring(1,str.length()-1);
}
String comma="\",\"";
String quot=(j==0)?"\"":"";
if(j==(csv[i].length-1)){ comma="\"\n"; }
result.append(quot);
result.append(str);
result.append(comma);
}
}
output.write(result.toString().trim());
output.close();
}
}
private String[][] csv;
public String[][] fgetcsv(String fileName,String encode) throws FileNotFoundException, IOException
{
csv=null;
try(BufferedReader input=new BufferedReader(new InputStreamReader(new FileInputStream(fileName),encode)))
{
ArrayList<ArrayList> rows=new ArrayList<>();
ArrayList<String> cols=new ArrayList<>();
String str="";
String line;
int rowsIndex=0;
int colsIndex=0;
boolean group=false;
int cnt=0;
while((line=input.readLine())!=null)
{
line=line.replaceAll("[ ]*[,][ ]*",",");
line=line+(String)"\n";
String[] parts=line.split(",");
for(int i=0;i<parts.length;i++)
{
int quotIn=(Integer)getQuotLength(parts[i],0)%2;
int quotOut=(Integer)getQuotLength(parts[i],-1)%2;
if(quotIn==1){ group=true; }
if(quotIn==1&"Out==1){ group=false; }
if("\"\n".equals(parts[i])){ group=true; cnt++; }
if("\"\n".equals(parts[i])&&cnt%2==0){ group=false; }
if("\"".equals(parts[i])&&group==true){ group=false; }
if(quotIn==1&"Out==0){ group=true; cnt++; }
if(quotIn==0&"Out==1){ group=false; }
parts[i]=("".equals(parts[i])||parts.length!=1)? parts[i]+"," : parts[i];
parts[i]=parts[i].replaceAll("\n,$","\n");
str+=parts[i];
if(group==false)
{
str=str.replaceAll(",$","");
str=str.trim();
cols.add(colsIndex,str);
str="";
colsIndex++;
}
if(group==false&&parts[i].indexOf((String)"\n")!=-1)
{
rows.add(rowsIndex,cols);
cols=new ArrayList<>();
colsIndex=0;
rowsIndex++;
}
}
}
csv=new String[rows.size()][rows.get(0).size()];
for(int i=0;i<rows.size();i++)
{
for(int j=0;j<rows.get(i).size();j++)
{
String result=(String)rows.get(i).get(j);
result=result.trim();
rows.get(i).set(j,result);
if(result.indexOf("\"")==0&&result.lastIndexOf("\"")==result.length()-1)
{
result=result.substring(1,result.length()-1);
}
try
{
csv[i][j]=result;
}
catch(ArrayIndexOutOfBoundsException pe)
{
continue;
}
}
}
input.close();
}
return csv;
}
}
カウンター
プロフィール
Author:negotoy
電気の勉強始めました!
テキストエディタを使ってプログラミングに挑戦中。fc2 ブログに公開しているテンプレート等は、自由にカスタマイズして、ご活用ください。プログラム実行の前に必ずコードの確認をお願いします。
最新記事
カテゴリ
カレンダー
リンク
月別アーカイブ
- 2018/04 (10)
- 2018/03 (9)
- 2018/02 (6)
- 2018/01 (5)
- 2017/12 (3)
- 2017/11 (15)
- 2017/10 (2)
- 2017/09 (7)
- 2017/08 (7)
- 2017/07 (5)
- 2017/06 (2)
- 2017/05 (5)
- 2017/04 (7)
- 2017/03 (8)
- 2016/07 (1)
- 2016/06 (2)
- 2016/05 (1)
- 2016/04 (1)
- 2016/03 (1)
- 2016/02 (1)
- 2016/01 (2)
- 2015/12 (1)
- 2015/11 (1)
- 2015/10 (2)
- 2015/06 (2)
- 2015/04 (5)
- 2015/03 (9)
- 2015/02 (7)
- 2014/10 (1)
- 2014/09 (2)
- 2014/08 (2)
- 2014/07 (1)
- 2014/06 (2)
- 2014/05 (6)
- 2014/04 (4)
- 2013/07 (2)
- 2013/06 (8)
- 2013/05 (5)
- 2013/04 (9)
- 2013/03 (2)
- 2013/02 (11)
- 2013/01 (18)
QRコード
