Quantcast
Channel: プログラム の個人的なメモ
Viewing all 860 articles
Browse latest View live

【Java】【Swing】テキストボックス ~ JTextField ~

$
0
0

サンプル

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.BevelBorder;

public class TextFieldDemo extends JFrame {
  private static final long serialVersionUID = 1L;

  public static void main(String args[]) {
    TextFieldDemo frame = new TextFieldDemo();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setTitle("JTextField Demo");
    frame.setBounds(100, 200, 400, 150);
    frame.setVisible(true);
  }

  public TextFieldDemo() {
    JPanel panel = new JPanel();

    JTextField text1 = new JTextField("テキスト1", 30);
    JTextField text2 = new JTextField("テキスト2");
    JTextField text3 = new JTextField("テキスト3");

    text1.setForeground(Color.GREEN);
    text1.setBackground(Color.YELLOW);
    text1.setSelectionColor(Color.BLACK);
    text1.setSelectedTextColor(Color.WHITE);
    text1.setSelectionStart(1);
    text1.setSelectionEnd(3);
    text1.setFont(new Font("MS ゴシック", Font.ITALIC, 30));
    text1.setCursor(new Cursor(Cursor.HAND_CURSOR));
    text1.setMargin(new Insets(5, 10, 5, 10));

    text2.setPreferredSize(new Dimension(100, 14));
    text2.setBorder(new BevelBorder(BevelBorder.LOWERED));
    
    text3.setEditable(false);

    panel.add(text1);
    panel.add(text2);
    panel.add(text3);

    this.getContentPane().add(panel);
  }
}


【Java】 byte配列⇔16進数文字列 の変換

$
0
0

■ はじめに

http://blogs.yahoo.co.jp/dk521123/33829893.html
などで、byte配列を16進数文字列 に変換する必要があり
以前は、以下のように独自にしていたが、簡単に実装できるのでメモ。

以前の実装: byte配列⇒16進数文字列 の変換

byte[] hashValues = messageDigest.digest();
StringBuffer stringBuffer = new StringBuffer();
for (byte hashValue : hashValues) {
   stringBuffer.append(String.format("%02x", hashValue));
}
returnValue = stringBuffer.toString();

修正後

returnValue = DatatypeConverter.printHexBinary(hashValues);

■ byte配列⇔16進数文字列 の変換

[1] Apache Commons Codec の Hex クラスの利用
[2] DatatypeConverter クラスの利用

コメント

[1]は、ライブラリなので以下からダウンロードしてJARをインポートする
https://commons.apache.org/proper/commons-codec/download_codec.cgi
[2]は、標準APIなのでダウンロード不要。

ただ、以下の「参考文献」で言われている『DatatypeConverter クラスが属するのが
javax.xml.bind パッケージであり、XML関連クラスである位置づけなので、
本来の用途として合っていないのではないかと思うと、筆者は少し気持ち悪く感じてしまいます』
ってのがあるが。。。

■ 注意:「Apache Commons Codec の Hex クラス」と「DatatypeConverter クラス」の違い

実は、このことが今回のブログの本当の目的

はじめに

 * 大した事じゃないかもしれないが、Hex.encodeHexString()で実装されていたコードを
   DatatypeConverter.printHexBinary() で置き換えたのだが、単体試験が通らなかった。

結論

 * 結果が、小文字・大文字の違いがある

  => もし、移行する際は気を付けて下さい

サンプル

import javax.xml.bind.DatatypeConverter;

import org.apache.commons.codec.binary.Hex;

public class Main {
  public static void main(String[] args) {
    System.out.println("Result1 : " + Hex.encodeHexString("あいう".getBytes()));
    System.out.println("Result2 : " + DatatypeConverter.printHexBinary("あいう".getBytes()));
  }
}

出力結果

結果が、小文字・大文字の違いがある
Result1 : 82a082a282a4
Result2 : 82A082A282A4


関連記事

【Java】ハッシュで暗号化する

http://blogs.yahoo.co.jp/dk521123/33829893.html

【Java】 Java で、 Email を送るには... ~ SMTP認証 / DIGEST-MD5 編 [2] ~

$
0
0

■ はじめに

 * JavaMail を使って、SMTP-AUTH の方式「DIGEST-MD5」でメール送信する方法を考える

■ 用語

SASL(サスル)

 * SASL : Simple Authentication and Security Layer
 * 認証や暗号化などのセキュリティに関する処理を行う層

CRAM-MD5

 * CRAM : Challenge-Response Authentication Mechanism
 * MD5形式でハッシュ化した認証情報を送って認証を行う

DIGEST-MD5

 * CRAM-MD5の弱点をカバーしてセキュリティをさらに向上させた形式

具体的には...
 * CRAM-MD5の欠点である辞書攻撃や総当たり攻撃に対する対処
 * Realm(ログイン領域)やURLの指定(これらはHTTPなどへの応用を想定している)や
   HMAC(keyed-Hashing for Message Authentication Code)による暗号化をサポート

Realm (レルム)

 * 日本語で、「領域、範囲、部門」
 * SMTP認証のドメイン名

参考文献

http://www.atmarkit.co.jp/ait/articles/0105/18/news002.html
http://www.wdic.org/w/WDIC/SASL
http://oxynotes.com/?p=4428

■ JavaMailのサポート範囲

DIGEST-MD5

 * DIGEST-MD5はサポート内
https://javamail.java.net/nonav/docs/api/com/sun/mail/smtp/package-summary.html
より抜粋

It can optionally use SMTP Authentication (RFC 2554)
 using the LOGIN, PLAIN, DIGEST-MD5, << ★ DIGEST-MD5はサポート ★
 and NTLM mechanisms (RFC 2595 and RFC 2831).

When using DIGEST-MD5 authentication, you'll also need to supply an appropriate realm;
 your mail server administrator can supply this information.
 You can set this
 using the mail.smtp.sasl.realm property, << ★ "mail.smtp.sasl.realm"を指定 ★
 or the setSASLRealm method on SMTPTransport. << ★ setSASLRealm()を指定 ★

CRAM-MD5

 * CRAM-MD5は???
 * 以下の参考文献の情報によると、GNU JavaMail(https://www.gnu.org/software/classpathx/javamail/javamail.html)
   はサポートしているらしい
http://it-mn-us.blogspot.jp/2009/02/javamail-mechanism.html
http://qa.atmarkit.co.jp/q/7147
http://frmmpgit.blog.fc2.com/blog-entry-129.html

関連記事

Java で、 Email を送るには... ~ JavaMail / テキストメール編 ~

http://blogs.yahoo.co.jp/dk521123/36230453.html

Java で、 Email を送るには... ~ JavaMail / 添付ファイル付きメール編 ~

http://blogs.yahoo.co.jp/dk521123/36230816.html

Java で、 Email を送るには... ~ SMTP認証編 [1] ~

http://blogs.yahoo.co.jp/dk521123/36491701.html

【Linux】【Postfix】 Postfix を設定する

【Java】【JAX-WS】 Webサービス / Metro [9] ~ タイムアウトを設定する / クライアントサイド ~

$
0
0

はじめに

 * 以下の Metro のユーザズガイド
https://metro.java.net/1.5/guide/HTTP_Timeouts.html
に従って、以下【ダメだった例】のように実装したが、タイムアウトが発生しなかった。
# サーバが、GlassFishじゃなかったから?

ただ、タイムアウトを実現できたので、メモしておく

【ダメだった例】タイムアウトが発生しなかった実装

Map<String, Object> context = ((BindingProvider)proxy).getRequestContext();

// 接続にかかった時間
context.put("com.sun.xml.ws.request.timeout", 2 * 1000);

// データ取得にかかった時間
context.put("com.sun.xml.ws.request.timeout", 2 * 1000);
JAXWSProperties.CONNECT_TIMEOUT について
https://jax-ws.java.net/nonav/jax-ws-20-fcs/arch/constant-values.html#com.sun.xml.ws.developer.JAXWSProperties.CONNECT_TIMEOUT

ポイント

Map<String, Object> context = ((BindingProvider) proxy).getRequestContext();

// 接続にかかった時間[ミリ秒]
context.put("com.sun.xml.internal.ws.request.timeout", 2 * 1000);

// データ取得にかかった時間[ミリ秒]
context.put("com.sun.xml.internal.ws.connect.timeout", 2 * 1000);

サンプル

動作環境

 * Windows10
 * Java1.8
 * Eclipse Mars.2 Release (4.5.2)
 * Tomcat v8.5.8
 * metro-2.3.1

サーバ側

http://blogs.yahoo.co.jp/dk521123/36139336.html
をベースに...
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlElement;

@WebService(name = "SampleWebService")
public class SampleWebService {
  @WebMethod
  public String sayYourAge(@XmlElement(required = true, nillable = false) @WebParam(name = "name") String name,
      @XmlElement(required = false, nillable = true) @WebParam(name = "age") Long age) {

    // ★ここで、実験のため、意図的にサーバ側に時間が掛かるようにした★
    try {
      Thread.sleep(10 * 1000L);
    } catch (InterruptedException ex) {
      ex.printStackTrace();
    }

    return name + "'s age is " + age + ".";
  }
}

クライアント側

http://blogs.yahoo.co.jp/dk521123/36140561.html
をベースに...
import java.net.URL;
import java.util.Map;

import javax.xml.ws.BindingProvider;

public class Main {

  public static void main(String[] args) {
    System.out.println("Start!");

    try {
      URL url = new URL("http://localhost:8080/SampleWebService/services/SampleWebService.ws?wsdl");
      SampleWebServiceService service = new SampleWebServiceService(url);
      SampleWebService proxy = service.getSampleWebServicePort();

      // ★ここ★
      Map<String, Object> context = ((BindingProvider) proxy).getRequestContext();
      // 接続にかかった時間[ミリ秒]
      context.put("com.sun.xml.internal.ws.request.timeout", 2 * 1000);
      // データ取得にかかった時間[ミリ秒]
      context.put("com.sun.xml.internal.ws.connect.timeout", 2 * 1000);

      long start = System.currentTimeMillis();
      String result = proxy.sayYourAge("Ken", 11L);
      long end = System.currentTimeMillis();
      System.out.println((end - start) + "ms");
      
      System.out.println("Result : " + result);
    } catch (Exception ex) {
      ex.printStackTrace();
    }
    System.out.println("Done");
  }
}

出力結果

Start!
javax.xml.ws.WebServiceException: java.net.SocketTimeoutException: Read timed out
	at com.sun.xml.internal.ws.transport.http.client.HttpClientTransport.readResponseCodeAndMessage(HttpClientTransport.java:195)
	at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.createResponsePacket(HttpTransportPipe.java:226)
	at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.process(HttpTransportPipe.java:217)
	at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.processRequest(HttpTransportPipe.java:130)
	at com.sun.xml.internal.ws.transport.DeferredTransportPipe.processRequest(DeferredTransportPipe.java:95)
	at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Fiber.java:1121)
	at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Fiber.java:1035)
	at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Fiber.java:1004)
	at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Fiber.java:862)
	at com.sun.xml.internal.ws.client.Stub.process(Stub.java:448)
	at com.sun.xml.internal.ws.client.sei.SEIStub.doProcess(SEIStub.java:178)
	at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:93)
	at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:77)
	at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:147)
	at com.sun.proxy.$Proxy35.sayYourAge(Unknown Source)
	at com.sample.webservice.client.stub.Main2.main(Main2.java:29)
	... 15 more
Done


関連記事

Webサービス / Metro [1] ~入門編 / サーバサイドの構築 ~

http://blogs.yahoo.co.jp/dk521123/36139336.html

Webサービス / Metro [2] ~入門編 / クライアントサイドの構築 ~

http://blogs.yahoo.co.jp/dk521123/36140561.html

Webサービス / Metro [5] ~応用編 / あれこれ ~

http://blogs.yahoo.co.jp/dk521123/36238319.html

【Java】【Swing】モジュール提供用テンプレートを作ってみた Part3 ~Login画面~

$
0
0

はじめに

http://blogs.yahoo.co.jp/dk521123/35027281.html
http://blogs.yahoo.co.jp/dk521123/36550446.html
で、モジュール提供用テンプレートを作ってみたが
ひとまず、申し訳ない程度にログイン画面も必要な場合もあるので
簡単なテンプレートを作ってみた

# JPasswordField を使ってるだけだが...

サンプル

LoginView.java

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;

public class LoginView extends JFrame implements ActionListener {
  /** Serial Version UID. */
  private static final long serialVersionUID = 1L;

  private static final String ID = "admin";
  private static final String PASSWORD = "password";
  
  private static final String FONT_NAME = "Arial";
  private static final int FONT_SIZE = 30;
  
  private static final String TITLE = "System Name";
  private static final String INPUT_TITLE = "Login";
  private static final String ICON = "etc/icon.jpg";
  private static final int X_COORDINATE_SCREEN = 800;
  private static final int Y_COORDINATE_SCREEN = 200;
  private static final int WIDTH_SCREEN = 600;
  private static final int HEIGHT_SCREEN = 400;
  
  private static final boolean IS_RESIZABLE = true;
  
  private JTextField idTextField;
  private JPasswordField passwordField;
  private JButton loginButton;
  
  public static void main(String[] args) {
    LoginView view = new LoginView();
    view.showScreen();
  }
  
  public LoginView() {
    // For North Panel
    JPanel northPanel = new JPanel();
    JLabel outputLabel = new JLabel("<html><h1>" + TITLE + "</h1></html>", JLabel.CENTER);
    northPanel.add(outputLabel);

    // For West Panel
    JPanel westPanel = new JPanel();
    westPanel.setVisible(false);

    // For East Panel
    JPanel eastPanel = new JPanel();
    eastPanel.setVisible(false);

    // For Center Panel
    JPanel centerPanel = new JPanel(new GridBagLayout());
    this.idTextField = new JTextField();
    this.idTextField.setFont(new Font(FONT_NAME, Font.PLAIN, FONT_SIZE));
    this.passwordField = new JPasswordField();
    this.passwordField.setFont(new Font(FONT_NAME, Font.PLAIN, FONT_SIZE));
    
    LineBorder insideBorder = new LineBorder(Color.BLACK, 1);
    TitledBorder titleBorder = new TitledBorder(insideBorder, 
        INPUT_TITLE, TitledBorder.LEFT, TitledBorder.TOP, new Font(FONT_NAME, Font.PLAIN, FONT_SIZE));
    centerPanel.setBorder(titleBorder);
    GridBagConstraints gridBagConstraints = new GridBagConstraints();
    gridBagConstraints.gridheight = 1;

    gridBagConstraints.gridx = 0;
    gridBagConstraints.insets = new Insets(5, 5, 5, 0);
    gridBagConstraints.anchor = GridBagConstraints.WEST;
    gridBagConstraints.gridy = 0;
    JLabel item1 = new JLabel("ID :");
    item1.setFont(new Font(FONT_NAME, Font.BOLD, FONT_SIZE));
    centerPanel.add(item1, gridBagConstraints);
    gridBagConstraints.gridy = 1;
    JLabel item2 = new JLabel("Password :");
    item2.setFont(new Font(FONT_NAME, Font.BOLD, FONT_SIZE));
    centerPanel.add(item2, gridBagConstraints);
    gridBagConstraints.gridy = 2;

    gridBagConstraints.gridx = 1;
    gridBagConstraints.weightx = 1.0;
    gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
    gridBagConstraints.gridy = 0;
    centerPanel.add(this.idTextField, gridBagConstraints);
    gridBagConstraints.gridy = 1;
    centerPanel.add(this.passwordField, gridBagConstraints);

    // For South Panel
    JPanel southPanel = new JPanel();
    FlowLayout southLayout = new FlowLayout();
    southLayout.setAlignment(FlowLayout.RIGHT);
    southPanel.setLayout(southLayout);
    this.loginButton = new JButton("Login");
    this.loginButton.setFont(new Font(FONT_NAME, Font.BOLD, FONT_SIZE));
    southPanel.add(this.loginButton);
    this.loginButton.addActionListener(this);

    // For Layout
    this.setLayout(new BorderLayout());
    this.getContentPane().add(northPanel, BorderLayout.NORTH);
    this.getContentPane().add(westPanel, BorderLayout.WEST);
    this.getContentPane().add(centerPanel, BorderLayout.CENTER);
    this.getContentPane().add(eastPanel, BorderLayout.EAST);
    this.getContentPane().add(southPanel, BorderLayout.SOUTH);

    this.setTitle(TITLE);
    this.setBounds(X_COORDINATE_SCREEN, Y_COORDINATE_SCREEN, WIDTH_SCREEN, HEIGHT_SCREEN);
    this.setResizable(IS_RESIZABLE);
    
    // Title ICON
    ImageIcon icon = new ImageIcon(ICON);
    this.setIconImage(icon.getImage());

    // For Close
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
  }
  
  public void showScreen() {
    this.setVisible(true);
  }
  
  @Override
  public void actionPerformed(ActionEvent e) {
    if (this.idTextField.getText() == null || this.idTextField.getText().equals("")) {
      JOptionPane.showMessageDialog(this, "ID is empty", "Error", JOptionPane.ERROR_MESSAGE);
      return;
    } else if (this.passwordField.getPassword() == null || this.passwordField.getPassword().length == 0) {
      JOptionPane.showMessageDialog(this, "Password is empty", "Error", JOptionPane.ERROR_MESSAGE);
      return;
    }
    
    String id = this.idTextField.getText();
    String password = new String(this.passwordField.getPassword());
    if (ID.equals(id) && PASSWORD.equals(password)) {
      OtherView view = new OtherView();
      view.setVisible(true);
      this.setVisible(false);
    } else {
      JOptionPane.showMessageDialog(this, "Login is failed...", "FAILED...", JOptionPane.INFORMATION_MESSAGE);
    }
  }
}

OtherView.java

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class OtherView extends JFrame implements ActionListener {
  private static final long serialVersionUID = 1L;
  JButton button;

  public OtherView() {
    // 閉じるボタン押下時のアプリケーションの振る舞いを決定
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // ウィンドウの初期サイズ(幅、高さ)をピクセル単位で設定
    this.setSize(320, 160);
    // ウィンドウの表示場所を規定
    this.setLocationRelativeTo(null);
    // タイトルの表示
    this.setTitle("Login is successful!");
    // JFrameよりContentPaneを取得
    Container contentPane = this.getContentPane();
    // ラベルのインスタンスを生成
    JLabel label = new JLabel("Login is successful!");
    // ボタンのインスタンスを生成
    this.button = new JButton("Return");
    // ボタンにイベントを追加
    this.button.addActionListener(this);
    // ラベルをContentPaneに配置
    contentPane.add(label, BorderLayout.CENTER);
    // ボタンをContentPaneに配置
    contentPane.add(this.button, BorderLayout.SOUTH);
  }

  @Override
  public void actionPerformed(ActionEvent ae) {
    if (ae.getSource() == this.button) {
      LoginView loginView = new LoginView();
      loginView.setVisible(true);
      this.setVisible(false);
    } else {
      System.exit(0);
    }
  }
}


関連記事

【Java】【Swing】モジュール提供用テンプレートを作ってみた Part1

http://blogs.yahoo.co.jp/dk521123/35027281.html

【Java】【Swing】モジュール提供用テンプレートを作ってみた Part2

http://blogs.yahoo.co.jp/dk521123/36550446.html

【Java】【Swing】モジュール提供用テンプレートを作ってみた Part3 ~Login画面~

http://blogs.yahoo.co.jp/dk521123/36572567.html

【Java】【Swing】Swing で、画面移動

http://blogs.yahoo.co.jp/dk521123/33127585.html

【Java】【Word】 Word テンプレートを読み込んで、Javaで操作する [1] ~ Apache POI / 応用編 ~

$
0
0

はじめに

http://blogs.yahoo.co.jp/dk521123/36584129.html
で、Apache POIを使って、Wordファイル作成までできたので
今回は「Word テンプレートを読み込んで、Javaでプレイスフォルダ「@@VER@@」を置換する」

サンプル

 * テンプレートを読み込んで「@@VER@@」を「Hello World!!」に置き換えるサンプル
  => ただし不十分で、表の中の文字置き換えには対応できていない(他にもありそうだが)ので注意

ReplaceWithPoiDemo.java

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;

public class ReplaceWithPoiDemo {

  public static void main(String[] args) throws FileNotFoundException, IOException {
    String inputFilePath = System.getProperty("user.dir") + "/template.docx";
    String outputFilePath = System.getProperty("user.dir") + "/output.docx";

    try (XWPFDocument document = new XWPFDocument(new FileInputStream(inputFilePath));) {
      for (XWPFParagraph paragraph : document.getParagraphs()) {

        int numberOfRuns = paragraph.getRuns().size();

        // Collate text of all runs
        StringBuilder stringBuilder = new StringBuilder();
        for (XWPFRun run : paragraph.getRuns()) {
          int position = run.getTextPosition();
          if (run.getText(position) != null) {
            stringBuilder.append(run.getText(position));
          }
        }

        // Continue if there is text and contains "@@VER@@"
        if (stringBuilder.length() > 0 && stringBuilder.toString().contains("@@VER@@")) {
          // Remove all existing runs
          for (int i = 0; i < numberOfRuns; i++) {
            paragraph.removeRun(i);
          }
          String text = stringBuilder.toString().replace("@@VER@@", "Hello World!!");
          // Add new run with updated text
          XWPFRun run = paragraph.createRun();
          run.setText(text);
          paragraph.addRun(run);
        }
      }
      document.write(new FileOutputStream(outputFilePath));
    }

    System.out.println("Done. See " + outputFilePath);
  }
}


関連記事

Java で Word の読み書きを行う ~ Apache POI / 入門編 ~

http://blogs.yahoo.co.jp/dk521123/36584129.html

Word テンプレートを読み込んで、Javaで操作する [1] ~ Apache POI / 応用編 ~

http://blogs.yahoo.co.jp/dk521123/36584422.html

Word テンプレートを読み込んで、Javaで操作する [2] ~ Apache POI / 応用編 ~

http://blogs.yahoo.co.jp/dk521123/36584475.html

Word テンプレートを読み込んで、Javaで操作する [3] ~ Apache POI / 応用編 ~

http://blogs.yahoo.co.jp/dk521123/36586498.html

【Java】【Word】 Word テンプレートを読み込んで、Javaで操作する [2] ~ Apache POI / 応用編 ~

$
0
0

はじめに

http://blogs.yahoo.co.jp/dk521123/36584422.html
の続き。表内の文字置き換えに対応することを考える

サンプル

 * テンプレートを読み込んで表内の「@@VER2@@」を「Hello World!!」に置き換えるサンプル

ReplaceInTableWithPoiDemo.java

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;

public class PoiDemo {

  public static void main(String[] args) throws FileNotFoundException, IOException {
    String inputFilePath = System.getProperty("user.dir") + "/template.docx";
    String outputFilePath = System.getProperty("user.dir") + "/output.docx";

    try (InputStream fis = new FileInputStream(inputFilePath); XWPFDocument document = new XWPFDocument(fis);) {
      List<XWPFParagraph> paragraphs = document.getParagraphs();

      for (int x = 0; x < paragraphs.size(); x++) {
        XWPFParagraph paragraph = paragraphs.get(x);
        System.out.println(paragraph.getParagraphText());
      }

      List<XWPFTable> tables = document.getTables();
      for (int x = 0; x < tables.size(); x++) {
        XWPFTable table = tables.get(x);
        List<XWPFTableRow> tableRows = table.getRows();
        tableRows.remove(x);
        for (int r = 0; r < tableRows.size(); r++) {
          System.out.println("Row " + (r + 1) + ":");
          XWPFTableRow tableRow = tableRows.get(r);
          List<XWPFTableCell> tableCells = tableRow.getTableCells();
          for (int c = 0; c < tableCells.size(); c++) {
            System.out.print("Column " + (c + 1) + ": ");
            XWPFTableCell tableCell = tableCells.get(c);
            // tableCell.setText("TAE");
            String tableCellVal = tableCell.getText();
            if ((c + 1) == 2) {

              if (tableCellVal != null) {
                if (tableCellVal.length() > 0) {
                  String replaecedText = null;
                  if (tableCellVal.contains("@@VER2@@")) {
                    replaecedText = tableCellVal.replace("@@VER2@@", "Hello World!");
                  }
                  if (replaecedText != null) {
                    removeParagraphs(tableCell);
                    tableCell.setText(replaecedText);
                  }
                } else {
                  // tableCell.setText("NULL");
                }
              }
            }
            System.out.println("tableCell.getText(" + (c) + "):" + tableCellVal);
          }
        }
        System.out.println("\n");
      }

      document.write(new FileOutputStream(outputFilePath));
    }

    System.out.println("Done. See " + outputFilePath);
  }

  private static void removeParagraphs(XWPFTableCell tableCell) {
    for (int i = 0; i < tableCell.getParagraphs().size(); i++) {
      tableCell.removeParagraph(i);
    }
  }
}

メモ

http://blogs.yahoo.co.jp/dk521123/36584422.html
と今回のコードを整理して、もう少しマシなコードを、以下の関連記事を参照のこと。
http://blogs.yahoo.co.jp/dk521123/36586498.html


関連記事

Java で Word の読み書きを行う ~ Apache POI / 入門編 ~

http://blogs.yahoo.co.jp/dk521123/36584129.html

Word テンプレートを読み込んで、Javaで操作する[1] ~ Apache POI / 応用編 ~

http://blogs.yahoo.co.jp/dk521123/36584422.html

Word テンプレートを読み込んで、Javaで操作する [3] ~ Apache POI / 応用編 ~

http://blogs.yahoo.co.jp/dk521123/36586498.html

【Java】【Word】 Java で Word の読み書きを行う ~ docx4j / 入門編 ~

$
0
0

Java で Word の読み書きを行うには...

[1] Apache POIを使用する

 → 以下の関連記事を参照のこと
http://blogs.yahoo.co.jp/dk521123/36584129.html
[2] docx4j を使用する

 → 今回は、「[2] docx4j を使用する」を取り上げる

設定

1) 以下のサイトから、「docx4j-community-X.X.X.zip(今回は「docx4j-community-3.3.1.zip」)」
   をダウンロードする
http://www.docx4java.org/downloads.html
2) 1)のファイルを解凍し、「docx4j-X.X.X.jar(今回は「docx4j-3.3.1.jar」)」および
   フォルダ「dependencies」配下のJARファイル(「antlr-X.X.X.jar」「avalon-framework-api-X.X.X.jar」など)
   を全てインポートする

サンプル

HelloWorld.java

https://github.com/plutext/docx4j/blob/master/src/samples/docx4j/org/docx4j/samples/NewDocxHelloWorld.java
import org.docx4j.Docx4J;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;

public class HelloWorld {
  public static void main(String[] args) throws Docx4JException {
    WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
    MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart();

    mainDocumentPart.addParagraphOfText("hello world");

    String filename = System.getProperty("user.dir") + "/HelloWorld.docx";
    Docx4J.save(wordMLPackage, new java.io.File(filename), Docx4J.FLAG_SAVE_ZIP_FILE);
    System.out.println("Saved " + filename);
  }
}

メモ

 * 最終的には、「Wordのテンプレートを読み込んで、その中の一部をJavaで編集したい」のだが
  以下のサンプルを参考に ${key1} みたいなプレイスフォルダを置いても、
  設定した値が一部のみ置き換わっただけで、全ての値を意図した通りに変更できなかった
https://github.com/plutext/docx4j/blob/master/src/samples/docx4j/org/docx4j/samples/VariableReplace.java


関連記事

【Java】Java で Excel の読み書きを行う

http://blogs.yahoo.co.jp/dk521123/36148986.html

【Java】Java で Word の読み書きを行う ~ Apache POI / 入門編 ~

http://blogs.yahoo.co.jp/dk521123/36584129.html

【Java】【Word】 Java で Word の読み書きを行う ~ Apache POI / 入門編 ~

$
0
0

はじめに

http://blogs.yahoo.co.jp/dk521123/36582301.html
でWordファイル作成までできたが、Apache POIでも同じことをやってみる

設定

1) 以下のサイトから、「poi-bin-X.XX-yyyyMMdd.zip
  (今回は「poi-bin-3.15-20160924.zip」)」をダウンロードする
https://poi.apache.org/download.html
2) 1)のファイルを解凍し、以下のJARファイルを全てインポートする

  * ファルダ「poi-X.XX」直下(今回は「poi-3.15」)のJARファイル(「poi-3.15.jar」「poi-ooxml-3.15.jar」など)
  * フォルダ「lib」配下のJARファイル(「commons-codec-1.10.jar」「commons-collections4-4.1.jar」など)
  * フォルダ「ooxml-lib」配下のJARファイル(「xmlbeans-2.6.0.jar」「curvesapi-1.04.jar」)

サンプル

HelloWorldPoi.java

* Hello World
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class HelloWorldPoi {

  public static void main(String[] args) {
    String outputfilepath = System.getProperty("user.dir") + "/sample.docx";
    try (OutputStream out = new FileOutputStream(new File(outputfilepath));
        XWPFDocument document = new XWPFDocument();) {
      XWPFParagraph paragraph = document.createParagraph();
      XWPFRun run = paragraph.createRun();
      run.setText("Hello World!");
      document.write(out);
      
      System.out.println("Done. See " + outputfilepath);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}


関連記事

Java で Word の読み書きを行う ~ Apache POI / 入門編 ~

http://blogs.yahoo.co.jp/dk521123/36584129.html

Word テンプレートを読み込んで、Javaで操作する [1] ~ Apache POI / 応用編 ~

http://blogs.yahoo.co.jp/dk521123/36584422.html

Word テンプレートを読み込んで、Javaで操作する [2] ~ Apache POI / 応用編 ~

http://blogs.yahoo.co.jp/dk521123/36584475.html

Word テンプレートを読み込んで、Javaで操作する [3] ~ Apache POI / 応用編 ~

http://blogs.yahoo.co.jp/dk521123/36586498.html

【Java】 Java で Excel の読み書きを行う

http://blogs.yahoo.co.jp/dk521123/36148986.html

【Java】Java で Word の読み書きを行う ~ docx4j / 入門編 ~

http://blogs.yahoo.co.jp/dk521123/36582301.html

【Java】 シリアル番号やパスワードの読みを振り仮名に変換するプログラムを考える

$
0
0

はじめに

http://blogs.yahoo.co.jp/dk521123/36538970.html
で以下のような問題があるって書いた。
~~~~~~~~~~~~
 * 以下の文字が紛らわしく間違うトラブルがあるとかないとか...

  + 数字の「0(ゼロ)」と英字の「O(オー)」
  + 数字の「1(イチ)」と英字の「l(エル)」or「I(アイ)」
  + 数字の「8(ハチ)」と英字の「B(ビー)」
~~~~~~~~~~~~

その解決策として
~~~~~~~~~~~~
 => カタカナで振り仮名振るなどの対策が必要かも...
~~~~~~~~~~~~
と書いたので、そのプログラムを書いてみる

サンプル

PasswordReader.java

import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.HashMap;

import javax.xml.bind.DatatypeConverter;

public class PasswordReader {

  public static void main(String[] args) {
    try {
      String samplePassword = createPassword();
      System.out.println("元ネタ : " + samplePassword);
      
      String reading = convertReading(samplePassword);
      System.out.println("振り仮名 : " + reading);
    } catch (NoSuchAlgorithmException ex) {
      ex.printStackTrace();
    }
  }

  private static final String DELIMITER = "・";
  private static final String NOT_SUPPORTED_CHARACTER = "??";

  private static HashMap<String, String> mapper = new HashMap<String, String>() {
    private static final long serialVersionUID = 1L;
    {
      // ここは、キーとして「対応する文字」と値として「振り仮名」を対応させる
      put("0", "ぜろ");
      put("1", "いち");
      put("2", "に");
      put("3", "さん");
      put("4", "よん");
      put("5", "ご");
      put("6", "ろく");
      put("7", "なな");
      put("8", "はち");
      put("9", "きゅー");
      put("A", "エー");
      put("B", "ビー");
      put("C", "シー");
      put("D", "ディー");
      put("E", "イー");
      put("F", "エフ");
      put("G", "ジー");
      put("H", "エッチ");
      put("I", "アイ");
      put("J", "ジェー");
      put("K", "ケー");
      put("L", "エル");
      put("M", "エム");
      put("N", "エヌ");
      put("O", "オー");
      put("P", "ピー");
      put("Q", "キュー");
      put("R", "アル");
      put("S", "エス");
      put("T", "ティー");
      put("U", "ユー");
      put("V", "ヴィ");
      put("W", "ダブリュー");
      put("X", "エックス");
      put("Y", "ワイ");
      put("Z", "ゼット");
    }
  };

  /**
   * 対象値を読みに変換する
   * 
   * @param targetValue
   *          対象値
   * @return 読み
   * @see http://blogs.yahoo.co.jp/dk521123/36538970.html
   */
  public static String convertReading(String targetValue) {
    StringBuilder returnValue = new StringBuilder();
    for (int i = 0; i < targetValue.length(); i++) {
      if (i != 0) {
        returnValue.append(DELIMITER);
      }

      String targetCharacter = String.valueOf(targetValue.charAt(i));
      if (mapper.containsKey(targetCharacter)) {
        returnValue.append(mapper.get(targetCharacter));
      } else {
        // 対応していない文字だったら「??」を表示
        returnValue.append(NOT_SUPPORTED_CHARACTER);
      }
    }

    return returnValue.toString();
  }

  // パスワード自動生成として
  // http://blogs.yahoo.co.jp/dk521123/36415526.html
  // とほぼ同じプログラムを使用(ここは、どうでもいい)
  private static int DEFAULT_PASSWORD_LENGTH = 8;
  private static String createPassword() throws NoSuchAlgorithmException {
    SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
    byte tokenBytes[] = new byte[DEFAULT_PASSWORD_LENGTH];
    random.nextBytes(tokenBytes);
    return DatatypeConverter.printHexBinary(tokenBytes).toUpperCase();
  }
}

出力結果

例1
元ネタ : 6FE57F268C28287E
振り仮名 : ろく・エフ・イー・ご・なな・エフ・に・ろく・はち・シー・に・はち・に・はち・なな・イー
例2
元ネタ : EB9AB77A93CAEBC9
振り仮名 : イー・ビー・きゅー・エー・ビー・なな・なな・エー・きゅー・さん・シー・エー・イー・ビー・シー・きゅー

関連記事

Java で、シリアル番号生成を考える

http://blogs.yahoo.co.jp/dk521123/36538970.html

セキュアなランダム文字列生成を考える

http://blogs.yahoo.co.jp/dk521123/36415526.html

【Java】【Word】 Word テンプレートを読み込んで、Javaで操作する [3] ~ Apache POI / 応用編 ~

$
0
0

はじめに

http://blogs.yahoo.co.jp/dk521123/36584422.html
http://blogs.yahoo.co.jp/dk521123/36584475.html
のコードを統合して整理する

# ループの嵐でパフォーマンス悪そうですが、そんなにハードに使わなければ問題ないかと...

サンプル

ValueReplacer.java

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;

public class ValueReplacer {
  public static void main(String[] args) {
    String inputFilePath = System.getProperty("user.dir") + "/template.docx";
    String outputFilePath = System.getProperty("user.dir") + "/output.docx";
    Map<String, String> mapper = new HashMap<String, String>() {
      private static final long serialVersionUID = 1L;
      {
        put("@@VER1@@", "Hello");
        put("@@VER2@@", "World");
        put("@@VER3@@", "Mike");
      }
    };

    try {
      replace(inputFilePath, outputFilePath, mapper);
    } catch (FileNotFoundException ex) {
      ex.printStackTrace();
    } catch (IOException ex) {
      ex.printStackTrace();
    }

    System.out.println("Done. See " + outputFilePath);
  }

  public static void replace(String inputTemplateWordFile, String outputWordFile, Map<String, String> convertMapping)
      throws FileNotFoundException, IOException {
    try (XWPFDocument document = new XWPFDocument(new FileInputStream(inputTemplateWordFile));) {
      replaceValues(document, convertMapping);
      replaceValuesInTables(document, convertMapping);

      save(document, outputWordFile);
    }
  }

  private static void save(XWPFDocument document, String outputWordFile) throws FileNotFoundException, IOException {
    document.write(new FileOutputStream(outputWordFile));
  }

  private static void replaceValues(XWPFDocument document, Map<String, String> convertMapping) {
    for (XWPFParagraph paragraph : document.getParagraphs()) {
      StringBuilder stringBuilder = new StringBuilder();
      for (XWPFRun run : paragraph.getRuns()) {
        int position = run.getTextPosition();
        if (run.getText(position) != null) {
          stringBuilder.append(run.getText(position));
        }
      }

      for (Map.Entry<String, String> map : convertMapping.entrySet()) {
        if (stringBuilder.length() > 0 && stringBuilder.toString().contains(map.getKey())) {
          for (int i = 0; i < paragraph.getRuns().size(); i++) {
            paragraph.removeRun(i);
          }

          String text = stringBuilder.toString().replace(map.getKey(), map.getValue());
          XWPFRun run = paragraph.createRun();
          run.setText(text);
          paragraph.addRun(run);
        }
      }
    }
  }

  private static void replaceValuesInTables(XWPFDocument document, Map<String, String> convertMapping) {
    for (XWPFTable table : document.getTables()) {
      for (XWPFTableRow tableRow : table.getRows()) {
        for (XWPFTableCell tableCell : tableRow.getTableCells()) {
          String tableCellValue = tableCell.getText();
          if (tableCellValue == null || tableCellValue.isEmpty()) {
            continue;
          }

          for (Map.Entry<String, String> map : convertMapping.entrySet()) {
            if (tableCellValue.contains(map.getKey())) {
              String replaecedText = tableCellValue.replace(map.getKey(), map.getValue());
              removeParagraphs(tableCell);
              tableCell.setText(replaecedText);
            }
          }
        }
      }
    }
  }

  private static void removeParagraphs(XWPFTableCell tableCell) {
    for (int i = 0; i < tableCell.getParagraphs().size(); i++) {
      tableCell.removeParagraph(i);
    }
  }
}

関連記事

Java で Word の読み書きを行う ~ Apache POI / 入門編 ~

http://blogs.yahoo.co.jp/dk521123/36584129.html

Word テンプレートを読み込んで、Javaで操作する [1] ~ Apache POI / 応用編 ~

http://blogs.yahoo.co.jp/dk521123/36584422.html

Word テンプレートを読み込んで、Javaで操作する [2] ~ Apache POI / 応用編 ~

http://blogs.yahoo.co.jp/dk521123/36584475.html

【MySQL】【Windows】 MySQL を複数インスタンスで起動させる ~Windows編~

$
0
0

手順

[1] MySQLのインストール場所(デフォルトなら「C:\ProgramData\MySQL\MySQL Server X.X」)
    にある「my.ini」をコピー&ペーストし、任意のファイル名(例「my2.ini」)にする

[2] [1]のファイル(「my2.ini」)を以下の「MySQL設定ファイルの編集例(my2.ini)」
    を参考に修正する

[3] コマンドプロンプトを管理者権限で実行し、
    以下のコマンドでWindowsサービスとして登録する
~~~~~~~~
[構文]
mysqld --install 【サービス名】 --defaults-file="【MySQL設定ファイルのパス】"

[例]
mysqld --install MySQL57_2 --defaults-file="C:\ProgramData\MySQL\MySQL Server 5.7\my2.ini"
~~~~~~~~

[4] 手順[2]の「datadir」で指定したフォルダ(例「Data2」)を新規作成しておく

[5] デフォルトの「Data」配下にある「mysql」「performance_schema」をコピーし、
    手順[4]のフォルダ配下にペーストする

[6] Windowsサービス(例「MySQL57_2」)を起動する
 → 今回作成したポート(例「23306」)で、デフォルトで使用していたMySQLのユーザ/パスワードから
     ログインできるか確認。

ファイル構成例

C:\ProgramData\MySQL\MySQL Server 5.7
 + my.ini  << デフォルトであるMySQLの設定ファイル
 + my2.ini << 今回、別インスタンスあげるMySQLの設定ファイル
 + Data << デフォルトであるMySQLのフォルダ
    + mysql
    + performance_schema
 + Data2 << 今回、別インスタンス
    + mysql
    + performance_schema

MySQL設定ファイルの編集例(my2.ini)

[mysqld]

# 中略

# The TCP/IP Port the MySQL Server will listen on
port=23306 # ★ここを修正。ポート番号★

# Path to installation directory. All paths are usually resolved relative to this.
# basedir="C:/Program Files/MySQL/MySQL Server 5.7/"

# Path to the database root
datadir=C:/ProgramData/MySQL/MySQL Server 5.7\Data2 # ★ここを修正(手順[4]のフォルダ)★

# The default character set that will be used when a new schema or table is
# created and no character set is defined
character-set-server=utf8

# 中略

# Server Id.
server-id=2 # ★ここを修正★


関連記事

MySQL を複数インスタンスで起動させる ~ Linux編 ~

http://blogs.yahoo.co.jp/dk521123/36493945.html

【MySQL】 MySQL での データ移行 を考える

$
0
0

方法

[1] mysqldump を使ってバックアップ
[2] Workbenchを使ってデータ移行
[3] SELECT-INERTでデータ移行


関連記事

データ追加 ~ INSERT文 / SELECT INSERT文 ~

http://blogs.yahoo.co.jp/dk521123/16106035.html

【Java】 Sun / Oracle JDK と OpenJDK について

$
0
0

OpenJDK とは

 * OpenJDK は、Oracle社が提供しているJDK(Oracle JDK(Java Development Kit))をオープンソース化したもの。
  => なので、完全フリー。GPL v2
 * Oracleは、OpenJDKをOracle JDKのコード・ベースとして使用している

公式サイト

http://openjdk.java.net/

Oracleサイトからの情報

http://www.oracle.com/technetwork/jp/java/javase/community/opensourcejdk-jsp-136417-ja.html

Oracle JDK と OpenJDKとの差異

 * ほぼ差異はない(パフォーマンス的にも)
 * ただし、Oracle JDKには、以下の差異がある
   + グラフィック・ラスタライザ
   + サード・パーティ・フォント
   + 追加ドキュメント

参考文献

Oracleサイトから提供されている資料
http://www.oracle.com/technetwork/jp/tutorials/java-mj12-qa-smith-1683420-ja.pdf
「OpenJDK と Oracle JDK の相違点」や「どちらを選択するか」が参考になる
Oracleサイトから提供されている資料
http://ossipedia.ipa.go.jp/nfs/pdf_pub/1007/208/671/671.pdf
 * 残念ながら古い資料なので、JDK1.8以降の記載は載っていないが、参考にはなると思う

【Java】【Swing】 テーブル ~ JTable ~

$
0
0

JTableあれこれ

セル選択時の状態表示

 * setColumnSelectionAllowed(boolean)/setRowSelectionAllowed(boolean) で制御
http://www.javadrive.jp/tutorial/jtable/index16.html

サンプル

* 基本編
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class TableSample extends JFrame {
  private static final long serialVersionUID = 1L;

  public static void main(String[] args) {
    TableSample sample = new TableSample();
    sample.setVisible(true);
  }
  
  public TableSample() {
    ArrayList<Person> people = new ArrayList<Person>() {
      private static final long serialVersionUID = 1L;
      {
        add(new Person(1L, "Mike", 23));
        add(new Person(2L, "Tom", 15));
        add(new Person(3L, "Kevin", 36));
        add(new Person(4L, "Cocolo", 13));
        add(new Person(5L, "Mike", 41));
      }
    };
    
    String[] columnNames = {"ID", "Name", "Age",};
    DefaultTableModel tableModel = new DefaultTableModel(columnNames, 0);
    JTable table = new JTable(tableModel);
    for(Person person : people){
        tableModel.addRow(toTableData(person));
    }

    JScrollPane scrollPane = new JScrollPane(table);
    scrollPane.setPreferredSize(new Dimension(400, 100));
    JPanel panel = new JPanel();
    panel.add(scrollPane);

    this.getContentPane().add(panel, BorderLayout.CENTER);
    this.setTitle("This is title");
    this.setSize(500, 300);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }
  
  private static String[] toTableData(Person person) {
    String[] returnValues = new String[3];
    returnValues[0] = person.getId().toString();
    returnValues[1] = person.getName();
    returnValues[2] = person.getAge().toString();
    return returnValues;
  }
}
* 応用編(テキストボックスとボタンを付けて検索機能にした)
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import javax.swing.JButton;
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.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

public class TableSample extends JFrame implements MouseListener, ActionListener {
  private static final long serialVersionUID = 1L;

  public static void main(String[] args) {
    TableSample sample = new TableSample();
    sample.setVisible(true);
  }

  private String[] columnNames = { "ID", "Name", "Age", };
  private List<Person> people;
  private JPanel tablePanel;
  private JScrollPane scrollPane;
  private DefaultTableModel tableModel;
  private JTable table;
  private JTextField textField;
  private JButton searchButton;

  private JPopupMenu popup;
  private JMenuItem copyMenuItem;

  public TableSample() {
    JPanel textAndButtonPanel = new JPanel();
    JLabel label = new JLabel("Target Name : ");
    textAndButtonPanel.add(label);
    this.textField = new JTextField();
    this.textField.setPreferredSize(new Dimension(100, 20));
    textAndButtonPanel.add(this.textField);
    this.searchButton = new JButton("Search");
    this.searchButton.addActionListener(this);
    textAndButtonPanel.add(this.searchButton);
    this.getContentPane().add(textAndButtonPanel, BorderLayout.NORTH);

    this.people = new ArrayList<Person>() {
      private static final long serialVersionUID = 1L;
      {
        add(new Person(1L, "Mike", 23));
        add(new Person(2L, "Tom", 15));
        add(new Person(3L, "Kevin", 36));
        add(new Person(4L, "Cocolo", 13));
        add(new Person(5L, "Mike", 41));
      }
    };

    this.tableModel = new DefaultTableModel(this.columnNames, 0);
    this.table = new JTable(this.tableModel);
    // this.table.setColumnSelectionAllowed(true);
    // this.table.setRowSelectionAllowed(true);
    for (Person person : this.people) {
      this.tableModel.addRow(toTableData(person));
    }
    this.table.addMouseListener(this);

    this.scrollPane = new JScrollPane(this.table);
    this.scrollPane.setPreferredSize(new Dimension(400, 100));
    this.tablePanel = new JPanel();
    this.tablePanel.add(this.scrollPane);

    this.getContentPane().add(this.tablePanel, BorderLayout.CENTER);

    // 右クリック
    this.popup = new JPopupMenu();
    this.copyMenuItem = new JMenuItem("コピー");
    this.copyMenuItem.addActionListener(this);
    this.popup.add(this.copyMenuItem);
    ;

    this.setTitle("This is title");
    this.setSize(500, 300);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }

  private static String[] toTableData(Person person) {
    String[] returnValues = new String[3];
    returnValues[0] = person.getId().toString();
    returnValues[1] = person.getName();
    returnValues[2] = person.getAge().toString();
    return returnValues;
  }

  @Override
  public void actionPerformed(ActionEvent actionEvent) {
    Object control = actionEvent.getSource();
    if (control == this.searchButton) {
      this.search();
    } else if (control == this.copyMenuItem) {
      this.copy();
    }
  }

  private void copy() {
    int[] rows = table.getSelectedRows();
    int[] columns = table.getSelectedColumns();

    StringBuffer buffer = new StringBuffer();
    for (int i = 0; i < table.getColumnCount(); i++) {

      TableColumn tableColumn = table.getColumnModel().getColumn(i);
      buffer.append((String) tableColumn.getIdentifier());

      if (i < table.getColumnCount() - 1) {
        // タブ文字を付加
        buffer.append("\t");
      } else {

        buffer.append("\n");
      }
    }

    for (int i = 0; i < rows.length; i++) {
      for (int j = 0; j < columns.length; j++) {
        Object cellValue = table.getValueAt(rows[i], columns[j]);
        buffer.append((String) cellValue);
        if (j < columns.length - 1) {
          buffer.append("\t");
        }
      }
      buffer.append("\n");
    }

    copyToClipboard(buffer.toString());
  }

  private void copyToClipboard(String copyString) {
    Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
    StringSelection contents = new StringSelection(copyString);
    clipboard.setContents(contents, null);
  }

  private void search() {
    String targetName = this.textField.getText();
    List<Person> peopleForFilter;
    if (targetName == null || targetName.isEmpty()) {
      peopleForFilter = this.people;
    } else {
      peopleForFilter = this.people.stream().filter(x -> x.getName().indexOf(targetName) != -1)
          .collect(Collectors.toList());
      if (peopleForFilter.isEmpty()) {
        JOptionPane.showMessageDialog(this, "Not Found", "Info", JOptionPane.INFORMATION_MESSAGE);
        return;
      }
    }

    this.tablePanel.remove(this.scrollPane);

    this.tableModel = new DefaultTableModel(this.columnNames, 0);
    this.table = new JTable(this.tableModel);
    // this.table.setColumnSelectionAllowed(true);
    // this.table.setRowSelectionAllowed(true);
    for (Person person : peopleForFilter) {
      this.tableModel.addRow(toTableData(person));
    }

    this.table.addMouseListener(this);
    this.scrollPane = new JScrollPane(this.table);
    this.scrollPane.setPreferredSize(new Dimension(400, 100));
    this.tablePanel.add(this.scrollPane);

    this.repaint();
    this.revalidate();
  }

  @Override
  public void mouseClicked(MouseEvent e) {
    // Do nothing
  }

  @Override
  public void mousePressed(MouseEvent e) {
    this.showPopup(e);
  }

  @Override
  public void mouseReleased(MouseEvent e) {
    this.showPopup(e);
  }

  @Override
  public void mouseEntered(MouseEvent e) {
    // Do nothing
  }

  @Override
  public void mouseExited(MouseEvent e) {
    // Do nothing
  }

  private void showPopup(MouseEvent event) {
    if (event.isPopupTrigger()) {
      this.popup.show(event.getComponent(), event.getX(), event.getY());
    }
  }
}


関連記事

右クリック時の動作 ~ JPopupMenu/JMenuItem ~

http://blogs.yahoo.co.jp/dk521123/36599406.html

【Java】【Swing】 右クリック時の動作 ~ JPopupMenu/JMenuItem ~

$
0
0

サンプル

PopupMenuSample.java

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;

public class PopupMenuSample extends JFrame implements MouseListener, ActionListener {
  private static final long serialVersionUID = 1L;

  public static void main(String[] args) {
    PopupMenuSample sample = new PopupMenuSample();
    sample.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    sample.setBounds(10, 10, 300, 200);
    sample.setVisible(true);
  }

  private JPopupMenu popup;
  private JMenuItem copyMenuItem;
  private JMenuItem pasteMenuItem;

  public PopupMenuSample() {
    JButton button = new JButton("button");
    button.addMouseListener(this);
    JPanel panel = new JPanel();
    panel.add(button);

    this.popup = new JPopupMenu();

    this.copyMenuItem = new JMenuItem("コピー");
    this.pasteMenuItem = new JMenuItem("ペースト");
    this.copyMenuItem.addActionListener(this);
    this.pasteMenuItem.addActionListener(this);
    this.popup.add(this.copyMenuItem);
    this.popup.add(this.pasteMenuItem);
    
    getContentPane().add(panel, BorderLayout.CENTER);
  }

  @Override
  public void mouseClicked(MouseEvent e) {
    // Do nothing
  }

  @Override
  public void mousePressed(MouseEvent e) {
    this.showPopup(e);
  }

  @Override
  public void mouseReleased(MouseEvent e) {
    this.showPopup(e);
  }

  @Override
  public void mouseEntered(MouseEvent e) {
    // Do nothing
  }

  @Override
  public void mouseExited(MouseEvent e) {
    // Do nothing
  }

  private void showPopup(MouseEvent event) {
    if (event.isPopupTrigger()) {
      this.popup.show(event.getComponent(), event.getX(), event.getY());
    }
  }

  @Override
  public void actionPerformed(ActionEvent actionEvent) {
    Object control = actionEvent.getSource();
    if (control == this.copyMenuItem) {
      JOptionPane.showMessageDialog(this, "Press Copy", "Info", JOptionPane.INFORMATION_MESSAGE);
    } else if (control == this.pasteMenuItem) {
      JOptionPane.showMessageDialog(this, "Press Paste", "Info", JOptionPane.INFORMATION_MESSAGE);
    }
  }
}


関連記事

テーブル ~ JTable ~

http://blogs.yahoo.co.jp/dk521123/36599082.html

【Java】 コレクション ~ Map / あれこれ 編~

$
0
0

■ Mapの初期化

Map<String, String> maps = 
    new HashMap<String, String>() {
  {
    put("X001", "first");
    put("X002", "second");
    put("X003", "third");
  }
};
http://pgnote.net/?p=32

■ 読み取り専用(Readonly)のMapにするには

* 「Collections.unmodifiableMap」「Collections.unmodifiableSortedMap」を使用する
Map<Integer, String> readonlyMaps = Collections.unmodifiableMap(maps);
http://docs.oracle.com/javase/jp/6/api/java/util/Collections.html

■ マップの定数化

* finalを付けても要素の追加や変更はできてしまうので、Collections.unmodifiableMap()を付ける
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

private static final Map<String, String> PRODUCT_MAP;

static {
   PRODUCT_MAP = Collections.unmodifiableMap(new ConcurrentHashMap<String, String>() {
      private static final long serialVersionUID = -5026360498609632073L;
      {
         put("X0001", "Apple");
         put("X0002", "Orange");
         put("X0003", "Melon");
      }
   });
}
http://sakuramochi702.hatenablog.com/entry/2013/10/08/114958

■ Mapをループさせる

キー・バリューどっちも使いたい場合

http://d.hatena.ne.jp/yamama_lanchester/20080530/1212122258
より

for(Map.Entry<String, String> map : maps.entrySet()) {
    System.out.println(map.getKey() + " : " + map.getValue());
}

キー・バリューどっちかを使いたい場合

http://yonchu.hatenablog.com/entry/20110216/1297857882
for (String key : map.keySet()) {
    System.out.println("キー : " + key);
}

for (String value : map.values()) {
    System.out.println("バリュー : " + value);
}

■ Map内のMax値の要素を取得する

Entry<String, Integer> maxEntry = Collections.max(maps.entrySet(),
        (entry1, entry2) -> entry1.getValue() - entry2.getValue());
http://stackoverflow.com/questions/5911174/finding-key-associated-with-max-value-in-a-java-map

■ Mapの最初と最後の要素を取得する

Set<Entry<String, Integer>> mapValues = maps.entrySet();
Entry<String, Integer>[] entryArrays = new Entry[mapValues.size()];
mapValues.toArray(entryArrays);

// 最初の要素
Entry<String, Integer> firstEntry = entryArrays[0];
// 最後の要素
Entry<String, Integer> lastEntry = entryArrays[mapValues.size() - 1];
http://blogs.candoerz.com/question/148143/java-linkedhashmap-get-first-or-last-entry.aspx

サンプル

Map内のMax値の要素を取得する
Mapの最初と最後の要素を取得する
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class Main {

  @SuppressWarnings("unchecked")
  public static void main(String[] args) {
    Map<String, Integer> maps = new HashMap<String, Integer>() {
      private static final long serialVersionUID = -1L;
      {
        put("X001", 76);
        put("X002", 96);
        put("X003", 56);
        put("X004", 100);
        put("X005", 28);
        put("X006", 87);
      }
    };
    
    // Max
    System.out.println("********* Max ***********");
    Entry<String, Integer> maxEntry = Collections.max(maps.entrySet(),
        (entry1, entry2) -> entry1.getValue() - entry2.getValue());
    System.out.println(maxEntry.getKey() + " " + maxEntry.getValue());

    // First/Last
    System.out.println("********* First/Last ***********");
    final Set<Entry<String, Integer>> mapValues = maps.entrySet();
    final Entry<String, Integer>[] entryArrays = new Entry[mapValues.size()];
    mapValues.toArray(entryArrays);

    Entry<String, Integer> firstEntry = entryArrays[0];
    System.out.println("First Key   : " + firstEntry.getKey());
    System.out.println("First Value : " + firstEntry.getValue());

    Entry<String, Integer> lastEntry = entryArrays[mapValues.size() - 1];
    System.out.println("Last Key    : " + lastEntry.getKey());
    System.out.println("Last Value  : " + lastEntry.getValue());
  }
}
出力結果
********* Max ***********
X004 100
********* First/Last ***********
First Key   : X001
First Value : 76
Last Key    : X006
Last Value  : 87

■ Mapを変換する

Map => List

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class MapUtil {
   public static  <T, V> List<V> toListValues(Map<T, V> map) {
      return new ArrayList<V>(map.values());
   }
   
   public static  <T, V> List<T> toListKeyValues(Map<T, V> map) {
      return new ArrayList<T>(map.keySet());
   }
}
http://the-pleiades.hateblo.jp/entry/2014/02/14/003533

■ カスタムソート

 * 以下の関連記事を参照のこと
http://blogs.yahoo.co.jp/dk521123/32156111.html

関連記事

【Java】 コレクション ~ Map 編~

http://blogs.yahoo.co.jp/dk521123/33002154.html

【Java】正規表現 [4] 文字列の抽出 ~Matcher.group() ~

$
0
0

■ 基本編

 * パターンの中で、マッチした部分を取り出したい部分を括弧()で囲う

構文

# 1, 2, ...
String result1 = matcher.group(1);
String result2 = matcher.group(2);
...

参考文献

http://www.javadrive.jp/regex/ref/index2.html

サンプル

■ 例1 : 正規表現で文字列抽出

 * 「【任意文字】Version【空白】:【空白】XXXXX【空白】」のフォーマットで
    "XXXXX"部分を抽出する
Main.java
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {

  public static void main(String[] args) {
    Pattern pattern = Pattern.compile("^.*Version[ \\t]*:[ \\t]*(.*)[ \\t]*$");
    Matcher matcher = pattern.matcher(" Version : 1.0.1");
    if (matcher.matches()) {
      System.out.println("Result : " + matcher.group(1));
    }
  }
}
出力結果
Result : 1.0.1

■ 例2 : コード内の要素分割

 * コード「【文字(A-Z)】【数字(2桁)】【文字(A-Z)】【数字(連番)】」のフォーマットで
    各要素を分割し、抽出する。
CodeSplitter.java
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CodeSplitter {

  public static void main(String[] args) {
    // Ex1
    System.out.println("**********************");
    try {
      String input1 = "A19A0001";
      List<String> results1 = split(input1);
      for (String result : results1) {
        System.out.println("Rsult1 : " + result);
      }
    } catch (Exception ex) {
      ex.printStackTrace();
    }

    // Ex2
    System.out.println("**********************");
    try {
      String input2 = "BB16ZZ0002";
      List<String> results2 = split(input2);
      for (String result : results2) {
        System.out.println("Rsult2 : " + result);
      }
    } catch (Exception ex) {
      ex.printStackTrace();
    }
    
    // Ex3:2要素目が3桁(エラー)
    System.out.println("**********************");
    try {
      String input3 = "BB161ZZ0002";
      List<String> results3 = split(input3);
      for (String result : results3) {
        System.out.println("Rsult3 : " + result);
      }
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }

  private static List<String> split(String targetCode) throws Exception {
    Pattern pattern = Pattern.compile("^([A-Z]+)([0-9]{2})([A-Z]+)([0-9]+)$");
    Matcher matcher = pattern.matcher(targetCode);
    if (!matcher.matches() || matcher.groupCount() != 4) {
      throw new Exception("Not Supported Code");
    }
    return Arrays.asList(matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(4));
  }
}

出力結果
**********************
Rsult1 : A
Rsult1 : 19
Rsult1 : A
Rsult1 : 0001
**********************
Rsult2 : BB
Rsult2 : 16
Rsult2 : ZZ
Rsult2 : 0002
**********************
java.lang.Exception: Not Supported Code
	at com.sample.regularex.CodeSplitter.split(CodeSplitter.java:52)
	at com.sample.regularex.CodeSplitter.main(CodeSplitter.java:39)

■ 例3 : 「key=Value # Comment」形式

プロパティ・ファイル(.properties) の「key=Value(# Comment)」形式を
保存する際に、Javaのデフォルトの標準ライブラリを使うと
http://blogs.yahoo.co.jp/dk521123/32137862.html
の注意書きに書いた通り、「コメントアウト(#)がなくなってまう」などの
問題があるので、自作しようかなーっと思って、その第一段階として
正規表現を使って「key=Value # Comment」形式を検索・パースできるソースを作ってみる
SampleRegularExpression.java
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SampleRegularExpression {

   public static void main(String[] args) {
      show("key1", "key1=value1 # comment1");
      show("sample.key2", " sample.key2 = value2 # comment2 ");
      show("sample.key3", " 	sample.key3	 =	 value3-1.value3-2	 # 	comment3	  ");
   }

   private static void show(String key, String target) {
      String pattern = String.format(
            "[ \\t]*(%s)[ \\t]*=[ \\t]*(.+)[ \\t]*#[ \\t]*(.+)[ \\t]*$",
            key.replace("\\.", "\\\\."));
      Matcher matcher = Pattern.compile(pattern).matcher(target);
      while(matcher.find()) {
          System.out.println(matcher.group(1));
          System.out.println(matcher.group(2));
          System.out.println(matcher.group(3));
      }
   }
}
出力結果
key1
value1 
comment1
sample.key2
value2 
comment2 
sample.key3
value3-1.value3-2	 
comment3	  

# * 余分な空白は含まれるがとりあえずは。。。本当はコメントがある時とない時でも問題なく動作させたいが。。。
参考文献
http://d.hatena.ne.jp/mtoyoshi/20081005/1223186868
http://javamemo.jpn.org/index.php?%5B%5B%C0%B5%B5%AC%C9%BD%B8%BD%5D%5D#content_1_11
http://d.hatena.ne.jp/mmasashi/20091030/1256919089

関連記事

正規表現 [1] 一致・不一致の判定 ~Matcher.matches() ~

http://blogs.yahoo.co.jp/dk521123/33605882.html

正規表現 [2] 複雑な文字列置き換え ~ replaceFirst / replaceAll ~

http://blogs.yahoo.co.jp/dk521123/34781790.html

正規表現 [3] 数字/文字の出現回数を数える ~Matcher.find() ~

http://blogs.yahoo.co.jp/dk521123/36448306.html

正規表現について

http://blogs.yahoo.co.jp/dk521123/26123295.html

Javaの文字列の扱い ~ String ~

http://blogs.yahoo.co.jp/dk521123/13687446.html

【Java】 漢字からカタカナを取得する [2] ~ kuromoji編 ~

$
0
0

はじめに

http://blogs.yahoo.co.jp/dk521123/36627267.html
のつづき。[1] kuromoji を使用する。

準備

http://www.atilika.com/ja/downloads/
でJARファイル(今回は「kuromoji-0.7.7.jar」)をダウンロードし、インポートするだけ。
使いやすい!

サンプル

import java.util.List;

import org.atilika.kuromoji.Token;
import org.atilika.kuromoji.Tokenizer;
import org.atilika.kuromoji.Tokenizer.Builder;
import org.atilika.kuromoji.Tokenizer.Mode;

public class Main {
  public static void main(String[] args) {
    System.out.println(toKana("山田 孝雄"));
    System.out.println(toKana("鈴木 崇"));
    System.out.println(toKana("斎藤 孝之"));
    System.out.println(toKana("渡辺 麻子"));
  }

  public static String toKana(String targetValue) {
    Builder builder = Tokenizer.builder();
    builder.mode(Mode.NORMAL);
    Tokenizer tokenizer = builder.build();
    List<Token> tokens = tokenizer.tokenize(targetValue);

    StringBuilder returnValue = new StringBuilder();
    for (Token token : tokens) {
      returnValue.append(token.getReading());
    }
    return returnValue.toString();
  }
}

出力結果

ヤマダ タカオ
スズキ タカシ
サイトウ タカユキ
ワタナベ アサコ


関連記事

漢字からカタカナを取得する [1] ~ 日本語形態素解析ライブラリ 基本編 ~

http://blogs.yahoo.co.jp/dk521123/36627267.html

漢字からカタカナを取得する [2] ~ kuromoji編 ~

http://blogs.yahoo.co.jp/dk521123/36627316.html

漢字からカタカナを取得する [3] ~ lucene-gosen編 ~

http://blogs.yahoo.co.jp/dk521123/36627324.html
Viewing all 860 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>