2025年3月
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
無料ブログはココログ

カテゴリー「Javaプログラミング」の記事

2014.09.17

[Java8] PSGぽい音を出す。

JavaでPSGぽい音を出すサンプルです。タイトルでJava8って書いてるけど、古いのでもいけると思います。(どのバージョンから出来るのかは確認してない)

package jp.hemohemo.testaudio;
 
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
 
public class TestAudio {
 
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        int SAMPLING_RATE = 44100;  // 44.1kHz(CDと同じ)
       
        // オーディオフォーマットを準備
        AudioFormat format = new AudioFormat(
                SAMPLING_RATE,      // サンプリング周波数
                16,                 // 16ビット
                2,                  // ステレオ
                true,               // 符号
                true                // ビッグエンディアン
        );
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
       
        SourceDataLine line;
        try {
            // データラインを取得
            line = (SourceDataLine)AudioSystem.getLine(info);
            // ラインを開く
            line.open();
        } catch (LineUnavailableException ex) {
            Logger.getLogger(TestAudio.class.getName()).log(Level.SEVERE, null, ex);
            return;
        }
 
        // 1秒間の波形データを準備
        int freq = 440;      // ラ(A)の周波数(440Hz)
        int vol = 2000;     // 音量
        byte[] datas = new byte[SAMPLING_RATE * 2 * 2]; // ステレオ、16ビットなので * 2 * 2なる
        int val;
        for(int i = 0; i < SAMPLING_RATE; i++) {
            int tmp = (int)(2 * i * freq / SAMPLING_RATE);
            if(tmp % 2 == 0) {
                val = vol;
            } else {
                val = -vol;
            }
            // 左チャンネル
            datas[i * 2 * 2 + 0] = (byte)((val >> 8) & 0xff);
            datas[i * 2 * 2 + 1] = (byte)(val & 0xff);
            // 右チャンネル
            datas[i * 2 * 2 + 2] = (byte)((val >> 8) & 0xff);
            datas[i * 2 * 2 + 3] = (byte)(val & 0xff);
        }
        line.start();
        // 波形データを書き込む
        line.write(datas, 0, datas.length);
        // 鳴り終わるのを待つ
        line.drain();
        line.stop();
        line.close();           
    }
}

まっ、見ればわかると思いますが、最初のほうでCDと同等の音質でデータラインを取得して、そこに440Hzの矩形波のデータを用意して書き込んでる。このfreqの値を変えると音程が変更でき、volを変更すると音量が変わる。
和音の出し方は別の音程の波形データを加算するだけでOK。ただし、オーバーフローしないようにしないといけない。

2014.09.13

NetBeansで日本語を入力すると落ちる - Така блог

リンク: NetBeansで日本語を入力すると落ちる - Така блог.

JDKを古いのにするのか。

2014.08.16

[Java8] JavaFX、マルチタッチ

Scene Builderをながめてると、マルチタッチに対応してそうなので試してみた。

サンプル:TestMultiTouch.zip

基本、"On Touch Moved"、"On Touch Pressed"、"On Touch Released"、"On Touch Stationary"の処理を実装すれば取れる。
あと、"On Touch Stationary"はリファレンスによるとタップアンドホールみたいなのを取れるみたいな感じで書かれているが実際取ってみたけど、いまいちよくわからない(^^;)
これが基本でジェスチャーのイベントも取れるようになっている"On Swipe *"がスワイプ、"On Zoom"が指二本で広げたり閉じたりするジェスチャ、"On Rotate"が指二本で回すようなジェスチャが取れる。

このサンプルは、マルチタッチ対応のタッチパネル付きのWindows8.1 PCで試した。 ズームと回転はMac+Magic Trackpadで取れるのを確認した。

2014.08.06

[Java8] JavaFX、ファイルのドラッグ&ドロップ

Controllerクラスに次のコードを追加してScene BuilderでAnchorPane(他のコントロールでもいい)の"On Drag Over"と"On  Drag Dropped"にそれぞれhandleDragOverとhandleDroppedを 割り当てる とFinderや エクスプローラーからファイルをドラッグアンドドロップで受け取ることができるようになる。ほかにもドラッグ&ドロップ関係のイベントがあるみたいだけど、これだけでファイルはとりあえず受け取れるようだ。(ほかのイベントはまだ調べていない(^^;))

    @FXML
    private void handleDragOver(DragEvent event) {
        // ドラッグボードを取得
        Dragboard board = event.getDragboard();
        if(board.hasFiles()) {  // ドラッグされているのがファイルなら
            // コピーモードを設定(これでマウスカーソルが矢印に+のやつになる)
            event.acceptTransferModes(TransferMode.COPY);
        }
    }

    @FXML
    private void handleDropped(DragEvent event) {
        // ドラッグボードを取得
        Dragboard board = event.getDragboard();
        if(board.hasFiles()) { 
            board.getFiles().stream().forEach((f) -> {
                System.out.println(f.getPath());
            });
            // ドロップ受け入れ
            event.setDropCompleted(true);
        } else {    // ファイル以外なら
            // ドロップ受け入れ拒否
            event.setDropCompleted(false);
        }
    }

2014.08.05

[Java8] JavaFX、とりあえずリストビュー

JavaFX Scene BuilderでListViewを追加して
Controllerクラスに↓を追加して、Scene BuilderでListViewのfx:id属性にlistViewを指定する。

    @FXML
    private ListView<String> listView;

あとは、

        listView.getItems().add("hoge”);

でリストに追加できる。まっ、これはとりあえず(^^;)

実際には、

    private ObservableList<String> items;

を定義しておいて、initializeあたりで

        items = FXCollections.observableArrayList();      
        listView.setItems(items);

を追加して、以後、itemsに追加したり削除したりするとリストが更新されるようになります。

つぎに、編集できるようにする。↓を追加。

        // 編集可能にする。
        listView.setEditable(true);       
        listView.setCellFactory(TextFieldListCell.forListView());

これで編集できるようになって、変更した内容がitemsに反映されます。

サンプル

2014.08.04

[Java8] JavaFX、閉じるの阻止

ウィンドウの閉じるボタンを押されたときの閉じないようにする方法は
こんなかんじになります。

        stage.setOnCloseRequest((WindowEvent event) -> {
                // 閉じるを阻止!
                event.consume();
        });

これをそのまま入れると強制終了しかできなくなるので注意w
閉じると困るときのみevent.consume()を呼ぶようにしましょうw

2014.07.29

Javaアプリケーションをexe化する方法

リンク: JavaアプリをExe化するLaunch4jの使い方と仕組み - seraphyの日記.

これでできた。

2014.07.24

[Java8] JavaFX、TextFieldの変更イベントを取る。

TextFieldの変更イベントを取るには、textPropertyにaddListenerすればよい。
newValueに値が入っている。

        textField.textProperty().addListener((ObservableValue observable, String oldValue, String newValue) -> {
                ・・・・・・
        });

2014.07.21

[Java,Android] CPUコア数の取得

JavaでCPUコア数の取得方法って、
意外となかなか見つけれなかったのでメモっとく。

        int core = Runtime.getRuntime().availableProcessors();

で、論理コア数が取れる。

Androidだと、SDKの説明によると
4.2以上は最大コア数で、
それ以前は、オンラインになっているコア数。つまり、省電力モードや熱などで動作コア数が変化する場合はそのコア数になるようです。

2014.07.20

[Java] 解像度を設定してJPEG保存

Javaで解像度(dpi)を設定してJPEG保存する方法を調べてみた。

次のようにするとできる。

    public static boolean saveJpeg(FileOutputStream outputStream, BufferedImage img, float compression, int dpi) {
        if(compression < 0 || compression > 1f) {
            return false;
        }
        ImageWriter iw = ImageIO.getImageWritersByFormatName("jpeg").next();
        try (ImageOutputStream ios = ImageIO.createImageOutputStream(outputStream)) {
            iw.setOutput(ios);

            JPEGImageWriteParam param = (JPEGImageWriteParam)iw.getDefaultWriteParam();
            param.setCompressionMode(JPEGImageWriteParam.MODE_EXPLICIT);
            param.setCompressionQuality(compression);

            IIOMetadata imageMeta = iw.getDefaultImageMetadata(new ImageTypeSpecifier(img), param);
            Element tree = (Element) imageMeta.getAsTree("javax_imageio_jpeg_image_1.0");
            Element jfif = (Element) tree.getElementsByTagName("app0JFIF").item(0);
            jfif.setAttribute("resUnits", "1");     // 解像度の単位をDPIにする。
            jfif.setAttribute("Xdensity", Integer.toString(dpi));   // 解像度設定
            jfif.setAttribute("Ydensity", Integer.toString(dpi));
            // メタデータを設定
            imageMeta.setFromTree("javax_imageio_jpeg_image_1.0", tree);

            // 書き込み
            iw.write(null, new IIOImage(img, null, imageMeta), param);
        } catch (IOException ex) {
            return false;
        }
        iw.dispose();
        
        return true;
    }