SQLの窓

2017年06月03日


VS(C#) : DataGrid に バインドを使用して JSON データの配列を表示する( Json.NET を使用 )



JSON 文字列を Json.NET で一行でデシリアライズします。その際、バインド用の ObservableCollection に直接セットするので、DataGrid には、DataContext にセットするだけで、表示用の列と行は自動作成されます

外部ライブラリ

JSON データの扱いには、Json.NET を使用します。ダウンロードして、Bin フォルダにある自分の環境に該当するフレームワークフォルダを ソリューションの中に置いて参照設定を行います。
※ net45 フォルダをコピーして使用しました / VS2012

JSON データ

https://lightbox.sakura.ne.jp/demo/json/syain_json.php

このデータを扱う為に以下のクラスを作成しています

Syain.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfAppDataGridFromWeb {
	class Syain {
		public string 社員コード { get; set; }
		public string 氏名 { get; set; }

		public string フリガナ { get; set; }
		public string 所属 { get; set; }

		private string _性別;
		public string 性別 {
			get {
				if (this._性別 == "0") {
					return "男";
				}
				else {
					return "女";
				}
			}
			set {
				this._性別 = value;
			}
		}
		public int 給与 { get; set; }
		public int? 手当 { get; set; }
		public string 管理者 { get; set; }

		public string 作成日 { get; set; }
		public string 更新日 { get; set; }

	}
}


画面

デフォルトで True になっていますが、バインドで列を自動作成させる為に 『AutoGenerateColumns="True"』を DataGrid に設定しています
<Window
	x:Class="WpfAppDataGridFromWeb.MainWindow"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	Title="MainWindow"
	Height="857.456"
	Width="1191.774">
	<Grid>
		<Button
			Content="Button"
			HorizontalAlignment="Left"
			Height="24"
			Margin="27,29,0,0"
			VerticalAlignment="Top"
			Width="122"
			Click="Button_Click" />
		<DataGrid
			x:Name="dataGrid"
			HorizontalAlignment="Left"
			Height="720"
			Margin="27,71,0,0"
			VerticalAlignment="Top"
			Width="1124"
			ItemsSource="{Binding}"
			IsReadOnly="True"
			MouseDoubleClick="dataGrid_MouseDoubleClick" />

	</Grid>
</Window>


処理
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Data.Odbc;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfAppDataGridFromWeb {

	public partial class MainWindow : Window {

		public MainWindow() {
			InitializeComponent();
			// ウインドウを中央へ
			this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
		}

		private void Button_Click(object sender, RoutedEventArgs e) {

			dataGrid.Columns.Clear();

			Console.WriteLine("クリックされました");
			Console.WriteLine(Directory.GetCurrentDirectory());

			string url = "https://lightbox.sakura.ne.jp/demo/json/syain_json.php";
			string result = "[\"error\"]";

			// 信頼性のある WebClient で インターネットアクセス
			WebClient wc = new System.Net.WebClient();
			wc.Encoding = System.Text.Encoding.UTF8;
			try {
				// 読み込み
				result = wc.DownloadString(url);
			}
			catch( Exception ex) {
				Console.WriteLine("WebClient エラー:" + ex.ToString());
			}

			// JSON オブジェクト配列 Newtonsoft.Json( net45 )
			ObservableCollection<Syain> syain_data = JsonConvert.DeserializeObject<ObservableCollection<Syain>>(result);
			// DataGrid にバインド
			dataGrid.DataContext = syain_data;

		}

		// DataGrid をダブルクリックした時の行データの取得
		private void dataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
			int row = dataGrid.SelectedIndex;
			if ( row >= 0 ) {
				Syain syain = (Syain)dataGrid.Items.GetItemAt(row);
				Debug.WriteLine(syain.社員コード + "|" + syain.氏名);

				MessageBox.Show(syain.社員コード + "|" + syain.氏名,
					"確認",
					MessageBoxButton.OK,
					MessageBoxImage.Information);
			}
		}

	}
}

※ HttpClient はバグがあるという話なので使用していません。

関連する記事

Swing の JTable に 1) WEBのJSON2次元配列。2) WEB の JSON配列 を取り込んで表示する( Google Gson と okhttp を使用 )

補足

以下の例では、AutoGenerateColumns="False" に設定して、列の定義をプログラムで行っています。このほうがアプリケーションとしては、列単位で仕様を決定しやすいので自由度が増すはずです。

※ データは JSON の2次元配列を使用しています
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Data.Odbc;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfAppDataGridFromWeb {

	public partial class MainWindow : Window {

		private DataGridTextColumn col;
		private ObservableCollection<Syain> syain_list = null;

		public MainWindow() {
			InitializeComponent();
			// ウインドウを中央へ
			this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
		}

		private void Button_Click(object sender, RoutedEventArgs e) {

			dataGrid.Columns.Clear();

			Console.WriteLine("クリックされました");
			Console.WriteLine(Directory.GetCurrentDirectory());

			string url = "https://lightbox.sakura.ne.jp/demo/json/syain_array.php";
			string result = "[\"error\"]";

			// 信頼性のある WebClient で インターネットアクセス
			WebClient wc = new System.Net.WebClient();
			wc.Encoding = System.Text.Encoding.UTF8;
			try {
				// 読み込み
				result = wc.DownloadString(url);
			}
			catch( Exception ex) {
				Console.WriteLine("WebClient エラー:" + ex.ToString());
			}

			// JSON 2次元配列 Newtonsoft.Json( net45 )
			string[][] syain_data = JsonConvert.DeserializeObject<string[][]>(result);

			// バインド用クラス
			Syain syain;
			// 列用
			col = null;
			// バインド用コレクション
			syain_list = new ObservableCollection<Syain>();

			foreach (string[] syain_row in syain_data) {

				// 初回
				if (col == null) {
					foreach (string syain_col in syain_row) {
						col = new DataGridTextColumn();
						col.Header = syain_col;
						col.Binding = new Binding(syain_col);
						dataGrid.Columns.Add(col);
					}
					continue;
				}

				syain = new Syain();
				syain.社員コード = syain_row[0];
				syain.氏名 = syain_row[1];
				syain.フリガナ = syain_row[2];
				syain.所属 = syain_row[3];
				syain.性別 = syain_row[4];
				syain.給与 = int.Parse(syain_row[7]);
				syain.手当 = (syain_row[8] == "" ? 0 : int.Parse(syain_row[8]));
				syain.管理者 = syain_row[9];
				syain.作成日 = syain_row[5];
				syain.更新日 = syain_row[6];
				// observablecollection に追加
				syain_list.Add(syain);

			}

			//// DataGrid にバインド
			dataGrid.DataContext = syain_list;

		}

		// DataGrid をダブルクリックした時の行データの取得
		private void dataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
			int row = dataGrid.SelectedIndex;
			if ( row >= 0 ) {
				Syain syain = (Syain)dataGrid.Items.GetItemAt(row);
				Debug.WriteLine(syain.社員コード + "|" + syain.氏名);

				MessageBox.Show(syain.社員コード + "|" + syain.氏名,
					"確認",
					MessageBoxButton.OK,
					MessageBoxImage.Information);
			}
		}

	}
}




タグ:C# Json.NET JSON
【VS(C#)の最新記事】
posted by lightbox at 2017-06-03 20:31 | Comment(0) | VS(C#) | このブログの読者になる | 更新情報をチェックする

Swing の JTable に 1) WEBのJSON2次元配列。2) WEB の JSON配列 を取り込んで表示する( Google Gson と okhttp を使用 )



環境準備

Eclipse は Pleiades の Neon です。Swing を使用する為の WindowBuilder のインストールとプロジェクト作成は、▼ 以下のリンク先を参照して下さい。

Pleiades All in One(NEON) で、Windows アプリを作成する手順( WindowBuilder + Swing デザイナー or SWT デザイナー[JFace] )

WEB へのアクセスは okhttp を使用します。ライブラリは MAVEN で取り込みます。okhttp は okio に依存しますが、リポジトリのファイルが壊れている場合は、okio の dependency も記述して、旧バージョンを順に試すといいでしょう。

JSON 文字列の扱いは、Google Gson を使用します

pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>WinApp</groupId>
  <artifactId>WinApp</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <dependencies>
    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.8.0</version>
    </dependency>
    <dependency>
      <groupId>com.squareup.okhttp3</groupId>
      <artifactId>okhttp</artifactId>
      <version>3.8.0</version>
    </dependency>    
  </dependencies>
  
  <build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.5.1</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
MAVEN プロジェクトへの変更は、プロジェクトを右クリックして『構成』から、選択できます

JTable は表示のみ対応した、JTableUnit と言うクラスを作成して使用しています。

JTableUnit
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

public class JTableUnit extends JTable {
	
	private JScrollPane _scrollPane;

	public JTableUnit( ) {
		super();
		_scrollPane = new JScrollPane(this);
	}
	
	@Override
	public boolean isCellEditable(int row, int column) {
		return false;
	}	
	
	public JScrollPane getScrollPane() {
		return _scrollPane; 
	}

	// ********************
	// 初期化
	// ********************
	public void reset() {

		DefaultTableModel dtm = (DefaultTableModel) this.getModel();
		dtm.setRowCount(0);
		
		int cols = this.getColumnCount();

		for( int i = cols-1; i >= 0; i-- ) {
			this.removeColumn((this.getColumnModel()).getColumn(i));
		}
		
		// データモデルも初期化
		dtm.setColumnCount(0);

	}
	// ********************
	// 行を全て削除
	// ********************
	public void clear(){
		DefaultTableModel dtm = (DefaultTableModel) this.getModel();
		dtm.setRowCount(0);
	}
	public void addColumn(String name) {
		DefaultTableModel dtm = (DefaultTableModel) this.getModel();
		dtm.addColumn(name);
	}
	public void setColumnTitle(String name,String title) {
		TableColumn tc = this.getColumn(name);
		 tc.setHeaderValue(title);
		 tc.setIdentifier(name);
	}
	public void addRow() {
		DefaultTableModel dtm = (DefaultTableModel) this.getModel();
		Object[] obj  = null;
		dtm.addRow(obj);
	}
	public void setColumn(int row, int col, String data) {
		this.setValueAt( data, row,  col );
	}
}


前提条件

JSON データは utf-8 です。

WEB 上の2次元配列データは https://lightbox.sakura.ne.jp/demo/json/syain_array.php です。

WEB 上の通常 JSON配列データは https://lightbox.sakura.ne.jp/demo/json/syain_json.php です。

3番目の処理では、JSON データのフォーマットに合わせたクラス(Syain) を作成して使用しています

public class Syain {

	String 社員コード;
	String 氏名;
	String フリガナ;
	String 所属;
	String 性別;
	String 給与;
	String 手当;
	String 管理者;

	String 作成日;
	String 更新日;
	
}


処理

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

import com.google.gson.Gson;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class Main extends JFrame {

	private JPanel contentPane;
	private JTableUnit table;
	private JPanel panel;

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Main frame = new Main();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	public Main() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 1000, 700);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);

		JButton buttonArray = new JButton("2次元配列");
		buttonArray.setBounds(10, 10, 112, 21);
		buttonArray.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {

				loadWebJsonArray();

			}
		});
		contentPane.add(buttonArray);

		JButton buttonProp = new JButton("JSONプロパティでタイトル");
		buttonProp.setBounds(134, 10, 218, 21);
		buttonProp.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {

				loadWebJson();

			}
		});
		contentPane.add(buttonProp);
		
		JButton buttonFix = new JButton("タイトルを内部で固定");
		buttonFix.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
				loadWebJsonFix();
				
			}
		});
		buttonFix.setBounds(364, 10, 180, 21);
		contentPane.add(buttonFix);

		JButton buttonClear = new JButton("行クリア");
		buttonClear.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				table.clear();
			}
		});
		buttonClear.setBounds(574, 10, 150, 21);
		contentPane.add(buttonClear);

		panel = new JPanel();
		panel.setBounds(12, 52, 960, 600);
		panel.setLayout(new BorderLayout(0, 0));
		contentPane.add(panel);

		table = new JTableUnit();
		panel.add(table.getScrollPane());

	}

	// *************************
	// 2次元配列
	// *************************
	private void loadWebJsonArray(){

		table.reset();

		String url = "https://lightbox.sakura.ne.jp/demo/json/syain_array.php";
		String result ="[\"error\"]";
		OkHttpClient client = new OkHttpClient();
		Request.Builder builder = new Request.Builder();
		builder.url(url);
		Request request = builder.build();

		Response response = null;
		try {
			response = client.newCall(request).execute();
			result = response.body().string();
		}
		catch (IOException e) {
			e.printStackTrace();
		}

		Gson gson = new Gson();
		String[][] data = gson.fromJson(result, String[][].class);

		int line_count = -1;
		int col_count = 0;
		for( String[] row : data ) {

			// 初回( タイトル部分 )
			if ( line_count == -1 ) {
				col_count = 0;
				for( String col : row ) {
					table.addColumn(String.format("col%d", col_count) );
					col_count++;
				}
				col_count = 0;
				for( String col : row ) {
					table.setColumnTitle(String.format("col%d", col_count), col );
					col_count++;
				}
				line_count++;

				// タイトル部分が一行あるので、次のデータをすぐに読む
				continue;
			}

			// 2回目以降( データ部分 )

			// 空行の追加
			table.addRow();
			col_count = 0;
			for( String col : row ) {
				// line_count に、
				table.setColumn(line_count, col_count, col );
				col_count++;
			}
			line_count++;
		}

	}

	// *************************
	// JSONプロパティでタイトル
	// *************************
	private void loadWebJson(){

		table.reset();

		String url = "https://lightbox.sakura.ne.jp/demo/json/syain_json.php";
		String result ="[\"error\"]";
		OkHttpClient client = new OkHttpClient();
		Request.Builder builder = new Request.Builder();
		builder.url(url);
		Request request = builder.build();

		Response response = null;
		try {
			response = client.newCall(request).execute();
			result = response.body().string();
		}
		catch (IOException e) {
			e.printStackTrace();
		}

		Gson gson = new Gson();
		// キーの順序を保持する為に、LinkedHashMap を使用
		LinkedHashMap<String,String>[] data = gson.fromJson(result, LinkedHashMap[].class);

		int line_count = 0;
		int col_count = 0;
		Set<String> keyset = null;
		Collection<String> values = null;
		Iterator<String> it;
		for( LinkedHashMap<String, String> row_data : data ) {

			// 初回( タイトル部分 )
			if ( keyset == null ) {
				keyset = row_data.keySet();

				col_count = 0;
				it = keyset.iterator();
				while( it.hasNext() ) {
					it.next();
					table.addColumn(String.format("col%d", col_count) );
					col_count++;
				}
				col_count = 0;
				it = keyset.iterator();
				while( it.hasNext() ) {
					String col_data = it.next();
					table.setColumnTitle(String.format("col%d", col_count), col_data );
					col_count++;
				}

			}

			// 空行の追加
			table.addRow();

			// 2回目以降( データ部分 )
			col_count = 0;
			values = row_data.values();
			it = values.iterator();
			while( it.hasNext() ) {
				String col_data = it.next();
				table.setColumn(line_count, col_count, col_data );
				col_count++;
			}
			line_count++;

		}

	}

	// *************************
	// タイトルを内部で固定
	// *************************
	private void loadWebJsonFix(){

		table.reset();
		for( int i = 0; i < 10; i++ ) {
			table.addColumn(String.format("col%d", i) );
		}
		table.setColumnTitle("col0", "社員コード");
		table.setColumnTitle("col1", "氏名");
		table.setColumnTitle("col2", "フリガナ");
		table.setColumnTitle("col3", "所属");
		table.setColumnTitle("col4", "性別");
		table.setColumnTitle("col5", "給与");
		table.setColumnTitle("col6", "手当");
		table.setColumnTitle("col7", "管理者");
		table.setColumnTitle("col8", "作成日");
		table.setColumnTitle("col9", "更新日");

		String url = "https://lightbox.sakura.ne.jp/demo/json/syain_json.php";
		String result ="[\"error\"]";
		OkHttpClient client = new OkHttpClient();
		Request.Builder builder = new Request.Builder();
		builder.url(url);
		Request request = builder.build();

		Response response = null;
		try {
			response = client.newCall(request).execute();
			result = response.body().string();
		}
		catch (IOException e) {
			e.printStackTrace();
		}

		Gson gson = new Gson();
		// データ部分のみ使用
		Syain[] data = gson.fromJson(result, Syain[].class);

		int line_count = 0;
		int col_count = 0;
		for( Syain row_data : data ) {

			// 空行の追加
			table.addRow();
			// 行データをセット
			table.setColumn(line_count, 0, row_data.社員コード );
			table.setColumn(line_count, 1, row_data.氏名 );
			table.setColumn(line_count, 2, row_data.フリガナ );
			table.setColumn(line_count, 3, row_data.所属 );
			table.setColumn(line_count, 4, row_data.性別 );
			table.setColumn(line_count, 5, row_data.給与 );
			table.setColumn(line_count, 6, row_data.手当 );
			table.setColumn(line_count, 7, row_data.管理者 );
			table.setColumn(line_count, 8, row_data.作成日 );
			table.setColumn(line_count, 9, row_data.更新日 );

			line_count++;

		}

	}

}


画面にデザイナで Panel を作成しておいて、JScrollPane 込みで作成されている JTableUnit を Panel に組み込んでいます(96、97 行)。

2番目の処理は、JSON のフォーマットに対応した クラスを使わずに、LinkedHashMap を使用して key 部分を取り出してタイトルに使用しています。

3番目の処理は、固定的な処理を行う一般的なアプリケーションで有用で、ソースの可読性が格段にアップします。


タグ:java swing JSON gson
posted by lightbox at 2017-06-03 18:25 | Comment(0) | java : Swing | このブログの読者になる | 更新情報をチェックする

Swing の JTable に 1) ローカルの CSV。2) WEB の CSV を取り込んで表示する



環境準備

Eclipse は Pleiades の Neon です。Swing を使用する為の WindowBuilder のインストールとプロジェクト作成は、▼ 以下のリンク先を参照して下さい。

Pleiades All in One(NEON) で、Windows アプリを作成する手順( WindowBuilder + Swing デザイナー or SWT デザイナー[JFace] )

WEB へのアクセスは okhttp を使用します。ライブラリは MAVEN で取り込みます。okhttp は okio に依存しますが、リポジトリのファイルが壊れている場合は、okio の dependency も記述して、旧バージョンを順に試すといいでしょう。

pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>WinApp</groupId>
  <artifactId>WinApp</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <dependencies>
    <dependency>
      <groupId>com.squareup.okhttp3</groupId>
      <artifactId>okhttp</artifactId>
      <version>3.8.0</version>
    </dependency>    
  </dependencies>
  
  <build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.5.1</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

MAVEN プロジェクトへの変更は、プロジェクトを右クリックして『構成』から、選択できます

JTable は表示のみ対応した、JTableUnit と言うクラスを作成して使用しています。

JTableUnit
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

public class JTableUnit extends JTable {
	
	private JScrollPane _scrollPane;

	public JTableUnit( ) {
		super();
		_scrollPane = new JScrollPane(this);
	}
	
	@Override
	public boolean isCellEditable(int row, int column) {
		return false;
	}	
	
	public JScrollPane getScrollPane() {
		return _scrollPane; 
	}

	// ********************
	// 初期化
	// ********************
	public void reset() {

		DefaultTableModel dtm = (DefaultTableModel) this.getModel();
		dtm.setRowCount(0);
		
		int cols = this.getColumnCount();

		for( int i = cols-1; i >= 0; i-- ) {
			this.removeColumn((this.getColumnModel()).getColumn(i));
		}
		
		// データモデルも初期化
		dtm.setColumnCount(0);

	}
	// ********************
	// 行を全て削除
	// ********************
	public void clear(){
		DefaultTableModel dtm = (DefaultTableModel) this.getModel();
		dtm.setRowCount(0);
	}
	public void addColumn(String name) {
		DefaultTableModel dtm = (DefaultTableModel) this.getModel();
		dtm.addColumn(name);
	}
	public void setColumnTitle(String name,String title) {
		TableColumn tc = this.getColumn(name);
		 tc.setHeaderValue(title);
		 tc.setIdentifier(name);
	}
	public void addRow() {
		DefaultTableModel dtm = (DefaultTableModel) this.getModel();
		Object[] obj  = null;
		dtm.addRow(obj);
	}
	public void setColumn(int row, int col, String data) {
		this.setValueAt( data, row,  col );
	}
}


前提条件

CSV は、ローカル・WEB 共に shift_jis です。
WEB 上のデータは https://lightbox.sakura.ne.jp/demo/json/syain_csv.php です。

処理

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class Main extends JFrame {

	private JPanel contentPane;
	private JTableUnit table;
	private JPanel panel;

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Main frame = new Main();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	public Main() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 1000, 700);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);

		JButton buttonLocal = new JButton("ローカルCSV読込み");
		buttonLocal.setBounds(10, 10, 150, 21);
		buttonLocal.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {

				loadCsv();

			}
		});
		contentPane.add(buttonLocal);

		JButton buttonWeb = new JButton("WEBCSV読込み");
		buttonWeb.setBounds(172, 10, 150, 21);
		buttonWeb.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {

				loadWebCsv();

			}
		});
		contentPane.add(buttonWeb);

		JButton buttonClear = new JButton("行クリア");
		buttonClear.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				table.clear();
			}
		});
		buttonClear.setBounds(334, 10, 150, 21);
		contentPane.add(buttonClear);

		panel = new JPanel();
		panel.setBounds(12, 52, 960, 600);
		panel.setLayout(new BorderLayout(0, 0));
		contentPane.add(panel);

		table = new JTableUnit();
		panel.add(table.getScrollPane());



	}

	// *************************
	// ローカルCSV読込み
	// *************************
	private void loadCsv(){

		table.reset();

		try {
			FileInputStream fis = new FileInputStream("C:\\Users\\lightbox\\Documents\\社員.csv");
			InputStreamReader isr = new InputStreamReader(fis, "MS932");
			BufferedReader br = new BufferedReader(isr);

			String cols_string;
			String[] col_data = null;
			int line_count = 0;
			while ( null != (cols_string = br.readLine() ) ) {

				// 空行を無視する
				if (cols_string.equals("")) {
					continue;
				}

				// 初回( タイトル部分 )
				if ( col_data == null ) {
					col_data = cols_string.split(",");

					// addColumn と  setColumnTitle は別々に実行する必要があります
					for( int i = 0; i < col_data.length; i++ ) {
						// カラムの ID を定義しています
						table.addColumn(String.format("col%d", i) );
					}
					for( int i = 0; i < col_data.length; i++ ) {
						// カラムの ID に対してタイトル文字列をセットしています
						table.setColumnTitle(String.format("col%d", i), col_data[i] );
					}
					continue;
				}

				// 2回目以降( データ部分 )
				col_data = cols_string.split(",");

				// 空行の追加
				table.addRow();
				for( int i = 0; i < col_data.length; i++ ) {
					// 行, カラム でデータをセット
					table.setColumn(line_count, i, col_data[i] );
				}
				line_count++;
			}

			br.close();
			isr.close();
			fis.close();
		}
		catch (Exception e) {
			e.printStackTrace();
		}

	}

	// *************************
	// WEBCSV読込み
	// *************************
	private void loadWebCsv(){

		table.reset();

		String url = "https://lightbox.sakura.ne.jp/demo/json/syain_csv.php";
		String result ="[\"error\"]";
		OkHttpClient client = new OkHttpClient();
		Request.Builder builder = new Request.Builder();
		builder.url(url);
		Request request = builder.build();

		Response response = null;
		try {
			response = client.newCall(request).execute();
			result = response.body().string();
		}
		catch (IOException e) {
			e.printStackTrace();
		}

		String[] row_data = result.split("\n");
		String[] col_data = null;
		int line_count = 0;
		for( String cols_string : row_data ) {

			// 空行を無視する
			if (cols_string.equals("")) {
				continue;
			}

			// 初回( タイトル部分 )
			if ( col_data == null ) {
				col_data = cols_string.split(",");
				for( int i = 0; i < col_data.length; i++ ) {
					// カラムの ID を定義しています
					table.addColumn(String.format("col%d", i) );
				}
				for( int i = 0; i < col_data.length; i++ ) {
					// カラムの ID に対してタイトル文字列をセットしています
					table.setColumnTitle(String.format("col%d", i), col_data[i] );
				}
				continue;
			}

			// 2回目以降( データ部分 )
			col_data = cols_string.split(",");

			// 空行の追加
			table.addRow();
			col_data = cols_string.split(",");
			for( int i = 0; i < col_data.length; i++ ) {
				// 行, カラム でデータをセット
				table.setColumn(line_count, i, col_data[i] );
			}
			line_count++;

		}
	}

}

画面にデザイナで Panel を作成しておいて、JScrollPane 込みで作成されている JTableUnit を Panel に組み込んでいます(82、83 行)。

okhttp での キャラクタセットは、サーバ側から送られた Content-Type を元に response.body().string() 実行時に自動変換されます。



タグ:swing java OkHttp
posted by lightbox at 2017-06-03 17:48 | Comment(0) | java : Swing | このブログの読者になる | 更新情報をチェックする

2017年05月29日


PHP : MastodonOAuthPHP の HttpRequest.php の http_request を public に書き換えて、ファイルアップロード

MastodonOAuthPHP

HttpRequest.php の http_request は、file_get_contents を使用した通信処理です。とてもいいサンプルですし、ソースも簡単に読めます。HttpRequest.php のみ upload_file.php と同じディレクトリに置いて実行します。

以下は http_request メソッドを public にして普通に使えるサンプルです。

upload_file.php
<?php
session_cache_limiter('nocache');
session_start();

header( "Content-Type: text/html; charset=utf-8" );

// **********************************************
// クラス定義の読み込み
// **********************************************
require_once("HttpRequest.php");

// **********************************************
// 【クラスの参照】
// HttpRequest の別名を Http として使用
// **********************************************
use \theCodingCompany\HttpRequest as Http;

$file_name = "./img.jpg";

$data = file_get_contents($file_name);
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_buffer($finfo, $data);
finfo_close($finfo);

$body = <<<DATA
-----------------------------7da1c519203ca
Content-Disposition: form-data; name="target"; filename="img.jpg"
Content-Type: {$mime}

{$data}
-----------------------------7da1c519203ca
Content-Disposition: form-data; name="send"

送信
-----------------------------7da1c519203ca--
DATA;

// バイト数
$size = strlen($body);

$header = array(
	"Content-Type" => "multipart/form-data; boundary=---------------------------7da1c519203ca",
	"Content-Length" => $size
);

// **********************************************
// アップロード
// **********************************************
$result = Http::http_request(
	"POST",
	"https://ドメイン/demo/file_upload.php", 
	$header, 
	$body
);

print_r( $result );

?>

※ データ区切りの boundary は、以前にダンプした実データのものを使用しています。
※ name="target" でアップロードしています。なので、受けの PHP では固定で処理しました。

file_upload.php
<?php
session_cache_limiter('nocache');
session_start();

header( "Content-Type: application/json; charset=utf-8" );


if ( $_SERVER['REQUEST_METHOD'] == "POST" ) {
 
	$upload = realpath ( './image' );
	$upload .= ( DIRECTORY_SEPARATOR . $_FILES['target']['name'] );
	if ( move_uploaded_file(
		$_FILES['target']['tmp_name'], $upload ) ) {
		$_POST['result']  = "アップロードに成功しました";
	}
	else {
		$_POST['result']  = "アップロードに失敗しました";
	}

}
else {
	$_POST['result']  = "POST メソッドを使用して下さい";
}

$_POST['files'] = $_FILES;

print json_encode($_POST, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE );
?>


関連する記事

MastodonOAuthPHP の HttpRequest.php の解説

WindowBuilder(Swing) で、WEBカメラを使用して画像を保存して okhttp で WEBサーバへアップロードする



タグ:通信 PHP
posted by lightbox at 2017-05-29 23:52 | Comment(0) | PHP + 通信 | このブログの読者になる | 更新情報をチェックする

2017年05月28日


Android Studio : エミュレータで Notification(通知)のテスト



こんな感じで結果的には表示されます。単なる動作確認のテストなので、MainActivity でボタンをクリックしたイベント内で呼び出しています。呼び出す前のステータスバーは、以下のようになります。



ボタンをクリックすると、以下のようになります。



このステータスバー(通知領域)から、下にドラッグ(エミュレータなので)すると通知画面が開きます。開いた通知をクリックすると、設定しておいた Google のドキュメントページをブラウザで開きます


Develop > API Guides > 通知

   public void notification(View view) {

        Log.i("lightbox", "notification");
        Notification.Builder builder = new Notification.Builder(getApplicationContext());

        // 通知内容の作成
        builder.setSmallIcon(android.R.drawable.ic_dialog_info);
        builder.setContentTitle("通知テスト");
        builder.setContentText("通知内容");
        builder.setSubText("説明");
        builder.setContentInfo("右下");
        builder.setPriority(Notification.PRIORITY_DEFAULT);
        builder.setAutoCancel(true);

        // 通知から呼び出される処理の作成
        Uri uri = Uri.parse("https://developer.android.com/guide/topics/ui/notifiers/notifications.html?hl=ja");
        // ブラウザ呼び出し
        Intent intent = new Intent(Intent.ACTION_VIEW,uri);
        // 通知に情報を与える PendingIntent の作成
        PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this,0, intent,PendingIntent.FLAG_CANCEL_CURRENT);
        // 通知にアクションを設定
        builder.setContentIntent(pendingIntent);

        // NotificationManager で通知
        NotificationManager manager = (NotificationManager)MainActivity.this.getSystemService(NOTIFICATION_SERVICE);
        // 第一引数は、アプリケーション内でユニークな通知の識別子
        manager.notify(0, builder.build());

    }

ボタンは今回は、単純に Button の属性で指定しています。public void メソッド(View view) な定義ならなんでもいいです。







posted by lightbox at 2017-05-28 15:44 | Comment(0) | Android Studio 2017 | このブログの読者になる | 更新情報をチェックする
container 終わり

フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

Android SDK ポケットリファレンス
改訂版 Webデザイナーのための jQuery入門
今すぐ使えるかんたん ホームページ HTML&CSS入門
CSS ドロップシャドウの参考デモ
PHP正規表現チェッカー
Google Hosted Libraries
cdnjs
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり