在不使用 IDE 的環境開發,如果不使用 makefile 來簡化編譯加執行的流程的話
真的很麻煩啊!!!
這篇會隨著 project 做大來更新
在不使用 IDE 的環境開發,如果不使用 makefile 來簡化編譯加執行的流程的話
真的很麻煩啊!!!
這篇會隨著 project 做大來更新
這兩行 Apple script
set volSettings to get volume settings set volume output volume ((output volume of volSettings) + 7)
是讓 Mac 的系統音量提高一格
同理,要讓它降一格就改成 -7 就行了
這支 Demo 是在 java 中執行上述的兩行 Apple script
完整 Code:
class AppleScriptTesting{ public static void main(String[] args){ Runtime runtime = Runtime.getRuntime(); String applescriptCommand = "set volSettings to get volume settings\n" + "set volume output volume ((output volume of volSettings) + 7)\n"; String[] script = { "osascript", "-e", applescriptCommand }; try{ Process process = runtime.exec(script); }catch(Exception e){ e.printStackTrace(); } } }
參考:
Java AppleScript: How to run a multi-line Applescript command from a Java program: https://alvinalexander.com/blog/post/java/how-run-multi-multiple-line-applescript-java-program
使用前:
使用後:
一開始我是找到這篇:
https://alvinalexander.com/apple/mac/java-mac-native-look/Putting_JMenuBar_on_Mac_men.shtml
把下面這行加入到程式碼裡:
System.setProperty("apple.laf.useScreenMenuBar", "true");
發現無效!
然後又看到別篇有人說要在main function的很早就要放 System.setProperty 這行了
我把它移到 main 的最上面了,還是不行!
後來是這篇成功了:
https://stackoverflow.com/questions/1654531/jmenubar-at-the-top-in-macosx
原來是我加入 JMenuBar 和原來的不一樣
要使用 setJMenuBar 的方式來加入選單列才可以用
System.setProperty("apple.laf.useScreenMenuBar", "true");
放到 Mac OS X的原生選單列上
我原來加入選單列的方式是:
Container contentPage = getContentPane(); contentPage.add(menubar, BorderLayout.NORTH);
我是先接觸 Android Studio 開發一些簡單的 App
後來想把 Java 底子打穩
才轉用 Eclipse 練習 Java 專案開發的
但是在剛轉換兩個 IDE 時,最讓我適應不良的地方就是
Eclipse 沒有像是 Android Studio 有自動提示程式碼的功能拉!!
像我這種還是練習中的新手,對各種 library、class 都還很不熟
一沒有提示就很難進行開發
所以就來記錄一下,怎麼樣讓 Eclipse 也有自動提示的功能
主要是參考這篇文章:電腦茶包|讓你的Eclipse更好用
不需要額外加裝套件,不過會需要多用一些電腦資源
也就是會有一點Lag
不過!!!為了自動提示,這點不方便不算什麼!!
也就是讓他判斷到這些字元,就觸發自動提示的功能
Java 程式端可以呼叫終端機來執行 apple script
靠的是 runtime.exec(args); 這行,來執行 args 的參數們
而實際執行的指令是
osascript -e 'display notification "Take a break" with title "Time up!!!" sound name ""' //可直接在終端機執行
我是放在 timer 倒數完結後(timeOut Override method),引發一個系統通知:
Runtime runtime = Runtime.getRuntime(); String[] args = { "osascript", "-e", "display notification \"Take a break\" with title \"Time's Up!!!\" sound name \"\"" }; try { Process process = runtime.exec(args); } catch (IOException ioError) { ioError.printStackTrace(); }
references:
https://alvinalexander.com/blog/post/java/how-run-execute-applescript-java-mac
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
除了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 檔
可以利用現成的程式來打包: 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 囉
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檔和編譯過的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裡,有些檔案沒有更改,就不會重新再編譯一次
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)); } }
參考: