[Mac App] A simple Menu Bar App in Java

import java.awt.AWTException;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.net.URL;

public class MenuBarIconTest {
    public static void main(String[] args) throws MalformedURLException {
        TrayIcon trayIcon = null;
         if (SystemTray.isSupported()) {
             // get the SystemTray instance
             SystemTray tray = SystemTray.getSystemTray();
             // load an image
             Image image = Toolkit.getDefaultToolkit().getImage(new URL("http://cdn1.iconfinder.com/data/icons/Hypic_Icon_Pack_by_shlyapnikova/16/forum_16.png"));
             // create a action listener to listen for default action executed on the tray icon
             ActionListener listener = new ActionListener() {
                 public void actionPerformed(ActionEvent e) {
                     System.out.println("action");
                     // execute default action of the application
                     // ...
                 }
             };
             // create a popup menu
             PopupMenu popup = new PopupMenu();
             // create menu item for the default action
             MenuItem defaultItem = new MenuItem("Do the action");
             defaultItem.addActionListener(listener);
             popup.add(defaultItem);
             /// ... add other items
             // construct a TrayIcon
             trayIcon = new TrayIcon(image, "Tray Demo", popup);
             // set the TrayIcon properties
             trayIcon.addActionListener(listener);
             // ...
             // add the tray image
             try {
                 tray.add(trayIcon);
             } catch (AWTException e) {
                 System.err.println(e);
             }
             // ...
         } else {
             // disable tray option in your application or
             // perform other actions
             //...
         }
         // ...
         // some time later
         // the application state has changed - update the image
         if (trayIcon != null) {
             //trayIcon.setImage(updatedImage);
         }

    }
}

 

reference:

https://stackoverflow.com/questions/13481504/creating-an-nsstatusitem-menubar-app-in-java

[Mac App] 以Java檔從零打造Mac App

  1. 打包寫好的 Java 程式,製作成 Jar 檔
  2. 將 Jar 檔打包成可以在 Mac 點兩下就執行的 Mac App

 

將編譯好的Class 打包成Jar

除了class檔們之外,還要製作一個純文字檔: manifest.mf (副檔名也可以是txt)

裡面內容為:(主要是要指定我們的起始MainClass是哪一個檔案)

Main-Class: HelloWorld



// 注意: 1. Main-Class寫完後,要往下空兩行
//       2. Main-Class的冒號後面記得要加一個空白

(假設我們的起始class檔為 HelloWorld.class的話,完成MainClass設定後,存檔為 manifest.mf)

 

再來打開終端機,輸入

$ jar cvfm MyJar.jar manifest.mf HelloWorld.class HelloWorld$1.class
// cvfm 的順序,會影響到後面接的參數順序

如果有很多個 class 檔也可以寫成
$ jar cvfm MyJar.jar manifest.mf *.class

就成功打包成為 MyJar.jar 檔

 

將 Jar 打包成 Mac App

可以利用現成的程式來打包: jar2app

從名字就可以推斷出,就是要將 jar 轉為 app 檔

這支程式是以終端機指令來進行包裝

 

安裝方式:

$ git clone https://github.com/Jorl17/jar2app
$ cd jar2app
$ chmod +x install.sh uninstall.sh
$ sudo ./install.sh

 

安裝完後,

將終端機目錄切換到 Jar 檔的所在目錄

$ jar2app MyJar.jar -i icon.icns

( icns 檔為 Mac App 的 icon 樣子,需事先準備好)

隨即就產生 MyJar.app 的 Mac App 囉

 

 

[Java] 找因數、判斷質數

import java.util.*;


public class PrimeFactorJudger{
	public static void main(String[] args){

		//從執行時的輸入字串找出所有因數、判斷是否質數
		for(String inputString:args){
			if(isNumeric(inputString)){
				int inputNumber = Integer.parseInt(inputString);
				printAllFactor(inputNumber);
				isPrime(inputNumber);
			}else{
				System.out.println(inputString + " is not Numeric");
			}
		}

		//找出100以內的質數
		/*
		for(int i=1; i<=100; i++){
			isPrime(i);
		}
		*/

	}

	public static void isPrime(int inputNumber){
		try{
			Queue<Integer> factors = findFactors(inputNumber);
			//factors = findFactors(inputNumber);
			if(factors.size() == 2){
				System.out.println(inputNumber+ " is Prime");
			}else{
				System.out.println(inputNumber+ " is not Prime");
			}
		}catch(Exception e){
			System.out.println("Exception!");
		}
	}


	public static void printAllFactor(int inputNumber){

		System.out.print(inputNumber+ "的因數有: ");
		System.out.println(findFactors(inputNumber));
	}

	public static Queue findFactors(int inputNumber){
		Queue<Integer> factors = new LinkedList<>();
		for(int i=1; i<=inputNumber; i++){
			if(inputNumber%i == 0){
				factors.add(i);
			}
		}
		return factors;
	}

	public static boolean isNumeric(String str){
		return str.matches("-?\\d+(\\.\\d+)?");  //match a number with optional '-' and decimal.
	}

}

 

如何執行:

javac PrimeFactorJudger.java
java PrimeFactorJudger 參數們
e.g.
java PrimeFactorJudger 13 100 20 39 abc

Java編譯器的參數怎麼下

假設我們想要把程式java檔和編譯過的class檔分開在不同資料夾下

project資料夾底下放著 src 和 classes 兩個資料夾

src: 放java檔(原始碼),目前裡面有兩個檔案:Main.java, Console.java

classes: 放class檔(編譯後),目前裡面為空

 

開啟terminal,將目錄切換到project資料夾,輸入

javac -verbose -sourcepath src -d classes src/Main.java

-verbose:可以看到編譯的過程

-sourcepath:之後接的參數src,就是我們存放java檔的資料夾

-d:之後接的參數classes,就是我們想要放編譯後的class檔的資料夾(可以把d想成destination或directory)

最後接的參數就是我們想要編譯的檔案,放在src資料夾底下的Main.java檔

 

也可以再多下一個參數

-cp/ -classpath:之後接的參數,在這個情況是classes資料夾,也就是如果整個專案中,在classes裡,有些檔案沒有更改,就不會重新再編譯一次

如何移除/編輯wordpress頁尾的版權? How to remove/edit the copyright footer of wordpress?

如何移除/編輯wordpress頁尾的版權?

Powered by WordPress 和 Theme: 字眼?

 

 

這一點很根據每個主題的不同要找不同的檔案來改

在這裡我舉Spacious為例:

主要程式碼放在footer.php裡

而實際function放在inc/functions.php裡

 

所以footer.php其實不用去動

只要找到inc/functions.php裡面和copyright字眼有關的add_action

改成自己想要的字即可

 

add_action( 'spacious_footer_copyright', 'spacious_footer_copyright', 10 );
/**
 * function to show the footer info, copyright information
 */
if ( ! function_exists( 'spacious_footer_copyright' ) ) :
function spacious_footer_copyright() {
    $site_link = '<a href="' . esc_url( home_url( '/' ) ) . '" title="' . esc_attr( get_bloginfo( 'name', 'display' ) ) . '" ><span>' . get_bloginfo( 'name', 'display' ) . '</span></a>';

    $wp_link = '<a href="'.esc_url( 'https://wordpress.org' ).'" target="_blank" title="' . esc_attr__( 'WordPress', 'spacious' ) . '"><span>' . __( 'WordPress', 'spacious' ) . '</span></a>';

    $tg_link =  '<a href="'.esc_url( 'https://themegrill.com/themes/spacious' ).'" target="_blank" title="'.esc_attr__( 'ThemeGrill', 'spacious' ).'" rel="designer"><span>'.__( 'ThemeGrill', 'spacious') .'</span></a>';

    /*$default_footer_value = sprintf( __( 'Copyright &copy; %1$s %2$s.', 'spacious' ), date( 'Y' ), $site_link ).' '.sprintf( __( 'Powered by %s.', 'spacious' ), $wp_link ).' '.sprintf( __( 'Theme: %1$s by %2$s.', 'spacious' ), 'Spacious', $tg_link );*/

    $default_footer_value = sprintf( __( 'Copyright &copy; %1$s %2$s.', 'spacious' ), date( 'Y' ), $site_link );

    $spacious_footer_copyright = '<div class="copyright">'.$default_footer_value.'</div>';
    echo $spacious_footer_copyright;
}
endif;

在此我把原本的 $default_footer_value 給comment掉

另外再創一個 $default_footer_value = sprintf( __( ‘Copyright &copy; %1$s %2$s.’, ‘spacious’ ), date( ‘Y’ ), $site_link );  => 那就是自己的名字加日期

網站要只換網址不換主機空間怎麼做?

原本使用的是twbbs.org的免費網域(Domain)

在今年底就要結束營運

只好趕快找別的免費網域來替代

 

前前後後花了好幾天在找好的免費網域

找到的不是不免費了 就是 主機商(Host)不給放網域

像是co.nz , .tk , .cf , .ga , .ml之類的

 

期間還有試過noip的DDNS

不過碰一碰後還是不太能理解怎麼運作的

想說時間不多還是先找個穩定的網域掛著吧

 

再來就是再想怎麼轉移網域了

大概也搞了整個下午跟晚上

弄完之後才發現

其實非常簡單QQ

我弄的太複雜了

 

首先:

先註冊好新網域,在網域商那邊掛上A紀錄、MX紀錄

例如這次我用的是交大nctu.me的免費網域

A紀錄就是直接指向主機商的ip

MX記錄就填上主機商給的

 

再來要確認新網域真的有運行了

通常放好A紀錄, MX紀錄之後,還要等個一兩個小時都算正常

但nctu.me不錯就是在幾分鐘內就可以運作了

 

確認方法:

nslookup newdomain.com => 如果有回傳ip就是有成功運行

ping newdomain.com => 如果有通就是有成功運行

 

新網域成功後就可以到主機商把新的DNS也掛上去

以我的免費主機商Freehostia為例

因為主機商不變,我的網站資料全部也都不變的情況下

只需要把新網域掛上去,並且導向原本的路徑上即可

 

到了這步確認一下,在瀏覽器打上新網域時,已經可以通原本的網站了

不過還沒結束,在wordpress後台的設定也要跟著改

後台->設定->一般: 裡面的WordPress網址 和 網站網址都要改

像我的情況是WordPress網址跟網站網址在不一樣目錄下

我就覺得很搞不清楚到底這兩個網址是差在哪裡

卡在這個觀念很久,但其實很簡單

舉例:

WordPress網址是 www.olddomain.com/wordpress

網站網址是 www.olddomain.com

只要把這兩個網址改成

WordPress網址是 www.newdomain.com/wordpress

網站網址是 www.newdomain.com

到這邊才是真正的完成

 

我還在那邊搞資料庫裡面的設定

好幾度改到前台後台都進不去

甚至新增了一個新主機,把所有資料都丟進去

想辦法改各種wp-config.php之類的檔案內容

真的是我想太複雜了,我只是換個網域而已啊~~~~~

 

 

然後在這過程中,發現了幾個問題

  1. 後台網址如果只是nowdomain.com/wp-login.php的話,非常容易被駭
  2. 舊網址不用了之後,還是要想辦法把舊網址導到新網址,以免有人存我的最愛是舊網址就找不到了

Java – calculate the day of the date (給定日期算出星期幾)

Input:

08 05 2015

Output:

WEDNESDAY

 

非常陽春的解法:(且不考慮到很過去的年份)

public class Solution {
    public static String getDay(String day, String month, String year) {
        /*
        * Write your code here.
        */
        int y=0, m=0, d=0, c=0, w=0;
        String weekday="";
        
        d = Integer.parseInt(day);
        y = Integer.parseInt(year.substring(2,4));
        c = Integer.parseInt(year.substring(0,2));
        m = Integer.parseInt(month);
        if(m == 1){
            m = 11;
            y--;
        }else if(m == 2){
            m = 12;
            y--;
        }else{
            m = m-2;
        }
       
        w = (int)(d+(2.6*m -0.2)+(5*(y%4))+3*y+(5*(c%4)))%7;
       
        //System.out.println("y="+y+ ", d="+d+", m="+m+", c="+c+", w="+w);        
        
        switch(w){
            case 0:
                weekday= "SUNDAY";
                break;
            case 1:
                weekday= "MONDAY";
                break;
            case 2:
                weekday= "TUESDAY";
                break;
            case 3:
                weekday= "WEDNESDAY";
                break;
            case 4:
                weekday= "THURSDAY";
                break;
            case 5:
                weekday= "FRIDAY";
                break;
            case 6:
                weekday= "SATURDAY";
                break;
        }
        
        return weekday;
    }

public static void main(String[] args) {
 Scanner in = new Scanner(System.in);
 String month = in.next();
 String day = in.next();
 String year = in.next();
 
 System.out.println(getDay(day, month, year));
 }
}

 

參考:

  1. wiki 高斯公式: https://zh.wikipedia.org/wiki/星期的計算#.E7.AE.97.E6.B3.95

Android – How to make a imageView full the screen?

在layout檔的屬性中加入

<ImageView
        android:id="@+id/trialIntervalImage"
        android:layout_width="2000dp"
        android:layout_height="1500dp"
        android:scaleType="fitXY"  //這行
        android:src="@drawable/trialintervalimage"
/>

android:scaleType=”fitXY” 會讓原圖滿版到整個螢幕

 

參考:

1.农民伯伯 Android2.2 API 中文文档系列(6) —— ImageView:

http://www.cnblogs.com/over140/archive/2010/09/19/1830703.html

Android – 觸發後只執行一次、要有時間性且更改UI的方法(AsycTask)

原意想要實作出像是delay多少秒之後要做UI更新

找到的方法是用timer、handler去做

 

不過用timer來計時每隔一段時間 重複執行某件事

再由handler去控制畫面UI的更新

-> 這個方法比較適合用在”重複執行”

 

對於這次我想要做的是,被觸發後,只想要執行一次

而這一次的動作,需要延遲幾秒鐘,且延遲完想要做些動作來恢復前面的改變

 

e.g. 在每個Trial間,想要插入間隔2000ms的空檔,實作方式用一張黑色底圖片蓋住原有圖,時間到後再把這張圖片拿掉

建立一個class繼承AsyncTask,其中要帶入三種參數<params, XXX, results > => 中間參數那項我忘記是什麼了

doInBackground是另一個會在背景執行thread,此範例是特地讓他delay一段時間

onPostExecute是執行完doInBackground後,會執行的一段程式,通常會用來顯示thread執行後的結果

在此例中,我拿來恢復原本的改變

private class TrialIntervalUpdate extends AsyncTask<Integer, Void, Integer> {
        @Override
        protected Integer doInBackground(Integer... params) {
            Log.e("doInBackground", "sleep "+params[0]+"ms");
            SystemClock.sleep(params[0]);
            return params[0];
        }

        protected void onPostExecute(Integer param)
        {
            Log.e("After "+ param + "ms","put img to back");
            trialIntervalImage.setImageAlpha(0);
        }
    }

 

創完class後,在想要觸發的地方,寫下:

            // 跑出來蓋住
            trialIntervalImage.bringToFront();
            trialIntervalImage.setImageAlpha(255);
            Log.e("clicked", "bringToFront and setAlpha 255");
            new TrialIntervalUpdate().execute(trialInterval);

先讓圖片跑到最上層、顯示不透明度255(最不透明 vs. 最透明是0)

再執行新的thread來實作delay,傳入想要delay的時間(int trialInterval)

 

 

參考:

1. 渺小且微不足道的晦暗 Android timer / sleep / delay / 更新 UI 的方法:

http://pontiffkao.blogspot.tw/2011/04/android-timer-sleep-delay-ui.html

2.  GIVEMEPASS’S ANDROID惡補筆記 無痛執行緒

http://givemepass.blogspot.tw/2011/10/blog-post.html

3. 老灰鴨的筆記本 【Android】AsyncTask – Thread 外的另一選擇

http://oldgrayduck.blogspot.tw/2013/01/androidasynctask-thread.html

4. Givemepass’s Android 惡補筆記 如何使用Handler

http://givemepass-blog.logdown.com/posts/296606-how-to-use-a-handler

[Java] Bubble sort practice

 

class BubbleSort{
	
	private static int HOW_MANY_RANDOM_NUMBER = 200;
	private static int MAX_RANDOM_NUMBER = 1000;

	private static int swap(int n1, int n2){
		return n1;
	}

	private static void bubble(int data[]){
		int cursor=0, index=0;
		for(index=0; index<data.length; index++){
			for(cursor=0; cursor<data.length-index-1; cursor++){
				if(data[cursor] > data[cursor+1]){
					data[cursor+1]= swap(data[cursor], data[cursor]=data[cursor+1]);
				}
			}
		}
	}

	private static void printArray(int data[]){
		System.out.print("[data]: ");
		for(int x : data){
			System.out.print(x+ " ");
		}
		System.out.println();
	}

	private static int[] numberGenerator(int howmany, int howbig){
		int tmp[] = new int[howmany];
		for(int x=0; x<tmp.length; x++){
			tmp[x] = (int)(Math.random()*howbig+1);
		}
		return tmp;
	}

	public static void main(String args[]){
		System.out.println("現在要取"+HOW_MANY_RANDOM_NUMBER+"個 1~"
			+MAX_RANDOM_NUMBER+" 的亂數資料");
		// 取HOW_MANY_RANDOM_NUMBER個 1~MAX_RANDOM_NUMBER 的亂數存進去data陣列中
		int data[]= numberGenerator(HOW_MANY_RANDOM_NUMBER, MAX_RANDOM_NUMBER);
		// 顯示data內的排序
		printArray(data);
		System.out.println("資料經過Bubble Sort之後");
		// 把data用bubble排序過
		bubble(data);
		// 再顯示出來
		printArray(data);
	}
}

練習重點:

1. bubble sort的概念:

將一串數列由小到大排序,像在水中的泡泡一樣,小泡泡浮上去、大泡泡往後排

2. bubble sort的時間複雜度:

最佳時間:O(n)

平均時間:O(n^2)

最差時間:O(n^2)

空間複雜度:O(1) => 指所需要佔用的空間大小,O(1)表示佔用空間固定,不受數列大小影響

代表一串數列經過bubble sort之後,所花的時間,

最好的情況下就是一開始就排好了,不需要再排序,但還是要走過一輪把數列的每個都檢查過一次,所以跟數列的數量一樣(n)

最差的情況就是大小順序完全相反,每個都需要重新排一次,也就是把數列的每個元素(n)都檢查過n*n次

* 如何證明時間複雜度呢?

將數列數量逐漸增加,觀察所需排序時間:

Desktop_—_-bash_—_96×24

Desktop_—_-bash_—_96×24

Desktop_—_-bash_—_96×24

Desktop_—_-bash_—_96×24

3. java的random:

private static int[] numberGenerator(int howmany, int howbig){
		int tmp[] = new int[howmany];
		for(int x=0; x<tmp.length; x++){
			tmp[x] = (int)(Math.random()*howbig+1);
		}
		return tmp;
	}

4. java的swap:

private static int swap(int n1, int n2){
		return n1;
}

要把x和y交換
使用: data[cursor+1]= swap(data[cursor], data[cursor]=data[cursor+1]);
代數簡化版: y= swap(x,x=y);

 

參考:

1. 小殘的城市光廊:http://emn178.pixnet.net/blog/post/93779892-氣泡排序法(bubble-sort)