發表文章

目前顯示的是有「Java」標籤的文章

Ubuntu 16.04解決flutter doctor的NoClassDefFoundError問題

  過了段時間沒用flutter,在處理Android License status unknown時,flutter doctor --android-licenses又遭遇 類似的問題 ,不過這次作業系統是Ubuntu 16.04上,總之我設定java成1.8就行了 $ flutter doctor --android-licenses Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema at com.android.repository.api.SchemaModule$SchemaModuleVersion.<init>(SchemaModule.java:156) at com.android.repository.api.SchemaModule.<init>(SchemaModule.java:75) at com.android.sdklib.repository.AndroidSdkHandler.<clinit>(AndroidSdkHandler.java:81) at com.android.sdklib.tool.sdkmanager.SdkManagerCli.main(SdkManagerCli.java:73) at com.android.sdklib.tool.sdkmanager.SdkManagerCli.main(SdkManagerCli.java:48) Caused by: java.lang.ClassNotFoundException: javax.xml.bind.annotation.XmlSchema at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) at java.base/java.l...

解決VS Code開java檔案時常跳出的小提示

圖片
解決VS Code開java檔案時常跳出的小提示 這個問題其實困擾的我很久,用VS Code開java檔案時常跳出的右下角小提示,如下圖 寫著: 抱歉啟用適用於Java的IntelliCode支援時發生錯誤,如需詳細資料... Java 11 or more recent is required to run the Java extension. 其實只要這樣做 下載 OpenJDK 11的zip檔案, 解開後放到特定目錄 例如我是放到, C:\tools\java-11-openjdk-11.0.8.10-2 (如果是下載用MSI安裝檔還要改安裝設定,直接zip解開就好) 在VS Code的settings.json中設定java.home "java.home" :  "C: \\ tools \\ java-11-openjdk-11.0.8.10-2" , 重開VS Code, 開java檔案就不會再冒出右下角小提示啦! 編譯Java若要其它版本 如果你要在VS Code底下用其他jdk版本編譯, 就還要設定java.configuration.runtimes,像是下面這樣      "java.configuration.runtimes" : [         {            "name" :  "JavaSE-1.8" ,            "path" :  "C: \\ Program Files \\ Java \\ jdk1.8.0_261" ,            "default" :  true         },     ...

[APP]從JNI傳送字串資料送到Java層遭遇\0問題

一般會認為,直接將字串資料直接呼叫到JNI的NewStringUTF, jstring的array中即可, 就像是下面這樣 char* p_str = ""; //你的字串資料 int len = ; //你的字串資料長度 jstring jstr = m_jenv->NewStringUTF(p_str); return jstr; 但是如果你的字串是中有包含'\0'字元時,就無法這麼做,例如:"abc\0cde\0",因為NewStringUTF是以\0作為結束符號,你得字串長度就會不正確。 所以要傳上述字串回到java層,就需要一套轉換方法,比較簡單的方式是使用jbyte陣列來傳遞,像是下面這樣。 jbyteArray jbarray = m_jenv->NewByteArray(len); m_jenv->SetByteArrayRegion(jbarray, 0, len, (const jbyte*)p_str); return jbarray; JNI回呼的Java方法大概會長這樣     public void OnCallbackTwoString (byte[] b) {         String s;         try {             s = new String(b, "UTF-8"); // or Charset.defaultCharset()             ....         } catch (UnsupportedEncodingException e) {             Log.e(TAG, "OnCallbackTwoString:", e);         }     } 在JNI回呼OnCallbackTwoString時使用"(...

Sample code for implementing the reflection interface Raw

Java與C++的函式參數傳遞比較

圖片
Java參數傳遞測試 Java的參數傳遞對於基本型態是複製,而物件型態則是類似C/C++的指標行為, 是複製物件的位址到函式中,所以在函式內assgin的新物件不影響外部變數所指的變數。 C++參數傳遞測試 而C++的參考則是會讓外部變數跟內部變數的狀態保持一致。 Java測試用程式碼 public class test {     static class MyObject {         public int iv = 0;         public String is = "initial field";         public MyObject io = this;         public MyObject() {         }         public MyObject(int primitive, String string, MyObject object) {             iv = primitive;             is = string;             io = object;         }     }     static public void setSomething(int primitive, String string, MyObject object) {         System.out.println("setSomething");         primitive = 200;     ...

Android簡短Webview範例

    private WebView mWebView = null;     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         Log.i(TAG, "new WebView(this)");         mWebView = new WebView(this);         WebSettings webViewSettings = mWebView.getSettings();         webViewSettings.setJavaScriptEnabled(true);         // packages/apps/Browser/src/com/android/browser/BrowserSettings.java         webViewSettings.setAllowContentAccess(false);         webViewSettings.setAppCacheEnabled(true);         webViewSettings.setDatabaseEnabled(true);         webViewSettings.setDomStorageEnabled(true);         mWebView.setWebViewClient(mWebViewClient);         mWebView.setWebChrome...

設定Ubuntu環境使用特定版本JDK

由於工作上需要,會在不同版本的jdk間做切換,所以會把切換JDK寫成設定的script,方便build code時引入。 當下console引入設定的方式 source ~/.your_jdk_setting Oracle JDK 1.6 #設定的Script內容 export JAVA_HOME=/usr/lib/jvm/jdk1.6.0_45 export JRE_HOME=/usr/lib/jvm/jdk1.6.0_45 export PATH=$JAVA_HOME:$PATH sudo update-alternatives --set javac     ${JAVA_HOME}/bin/javac sudo update-alternatives --set javah     ${JAVA_HOME}/bin/javah sudo update-alternatives --set javadoc   ${JAVA_HOME}/bin/javadoc sudo update-alternatives --set javap     ${JAVA_HOME}/bin/javap sudo update-alternatives --set jar       ${JAVA_HOME}/bin/jar sudo update-alternatives --set jarsigner ${JAVA_HOME}/bin/jarsigner sudo update-alternatives --set java      ${JAVA_HOME}/bin/java if [ $? -ne 0 ]; then   sudo update-alternatives --set java    ${JRE_HOME}/bin/java fi sudo update-alternatives --set keytool   ${JAVA_HOME}/bin/keytool if [ $? -ne 0 ]; then   sudo update-alt...

Install and setup JDK 1.6 for Ubuntu 14.04

先從Oracle下載JDK 解壓縮JDK chmod +x jdk-6u45-linux-x64.bin ./jdk-6u45-linux-x64.bin sudo mv jdk1.6.0_45 /usr/lib/jvm/ 設定所需要的工具 最後的參數32767是priority,數值較大的會優先被使用 sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk1.6.0_45/bin/javac 32767 sudo update-alternatives --install /usr/bin/java  java  /usr/lib/jvm/jdk1.6.0_45/bin/java  32767 sudo update-alternatives --install /usr/bin/javah javah /usr/lib/jvm/jdk1.6.0_45/bin/javah 32767 sudo update-alternatives --install /usr/bin/javadoc   javadoc   /usr/lib/jvm/jdk1.6.0_45/bin/javadoc   32767 sudo update-alternatives --install /usr/bin/javap     javap     /usr/lib/jvm/jdk1.6.0_45/bin/javap     32767 sudo update-alternatives --install /usr/bin/jar       jar       /usr/lib/jvm/jdk1.6.0_45/bin/jar       32767 sudo update-alternatives --install /usr/bin/jarsigner jarsigner /usr/lib/jvm/jdk1.6.0_45/bin/jarsigner 32767...

Java小程式:貝茲曲線

這支程式是利用4點繪製一條貝茲曲線。 參考的程式碼在 這裡 ,我主要是將成是改寫成Java Application並加上一點點註解。 程式碼 import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; public class BzWindow extends JFrame implements ActionListener { /** * Eclipse 自動產生的數值,請無視。 */ private static final long serialVersionUID = -9060807186493274426L; // 資料結構 private Point[] coordlist; // 控制點 private int numpoints; // 控制點數目 // 貝茲曲線參數 double t; // the time interval double k = .025; // time step value for drawing curve int moveflag = 5; // flag to notify if user is moving a point boolean poly = true; // 是否要繪製控制點(沒畫還是可以移動控制點) JButton...

Java:建立有泛型的Collection陣列

最近遇到的問題,想將JMenuItem分成三類,每個類別要能動態增減,不過減得機率很少,所以建立了ArrayList帶有泛型的Collection陣列,不過卻不能直接的建立,該如何解決!? 關鍵詞: create array of java generic collection import java.util.ArrayList; import javax.swing.JMenuItem; /** 建立如何建立包函泛型的Collection陣列。 */ class ArrayOfGenericCollection { public static void main(String [] args) { // 最直覺的寫法,不過這個寫法是無法通過編譯的。 //ArrayList<JMenuItem> gat[] = new ArrayList<JMenuItem>[10]; // 下面的寫法是利用Java陣列的基本概念,加上轉型, // 不過因為動態轉型所以編譯帶有警告。 // 且執行時期因為Object無法轉成ArrayList,所以這樣也行不通。 //ArrayList<JMenuItem> gat2[] = (ArrayList<JMenuItem>[])new Object[10]; // 上面的寫法,既然無法將Object轉成ArrayList, // 那我們就建立一個不帶泛型標記的ArrayList // (有標記的就是一開始的寫法) // 編譯加執行成功!! ArrayList<JMenuItem> gat3[] = (ArrayList<JMenuItem>[])new ArrayList[10]; for (int i=gat3.length-1; i>=0; --i) gat3[i] = new ArrayList<JMenuItem>(5); System.out.println("gat3[1].size()="+gat3[1].size()); // 轉型少了泛型也是可以的,因為隱含轉型也合法。 // 同樣的,編譯加執行成功!! ArrayList...

Java Puzzlers: 22. Dupe of URL

這隻程式會做什麼事情? public class BroswerTest { public static void main(String[] args) { System.out.println("iexplore"); http://www.google.com.tw System.out.println(":maximize"); } } 看出來了嗎? 其實它只會印字而已。 讓我們排版一下,這樣應該就瞭解了 public class BroswerTest { public static void main(String[] args) { System.out.println("iexplore"); http: //www.google.com.tw System.out.println(":maximize"); } } http: 是個label,在Java中也是有Label,是用在loop跳出時指定用的。 而// 則是整行註解,把後面的東西都註解掉了,所以這個URL可以編譯其實只是個假象。 上一篇Puzzlers: Java Puzzlers: 38.The Unwelcome Guest

Java 小程式:AES加解密實作

這是大三的資訊安全導論的期末Poject,雖然是以組為單位作的Project,但是本組只有我的期中考分數很差,分數是落在底標的部份,知道分數以後我就趕快的將期末這個Project搞好,期望倚靠程式Project得個高分,來彌補其中考的低分:P AES 的鎖鑰產生器 AesKeyGenerator 實作了亂數產生鎖鑰與指定密碼長度建立鎖鑰的方法。 AES 的抽象加解密器 AbstractAesCryptor 實作了AES的一個加密單位State的加解密方法,加解密流程則需自行實作。 這份程式碼出來的已是我改寫過的版本了,之前寫的更是錯綜複雜。至於之後的加密流程,如:ECB、CBC、CTR等等,由於寫的實在不好,都和GUI介面的綁在一起,就不獻醜了。 2018/05/02 因為太多人會點我上面的文件想要參考,雖然code滿亂的,但是我還是把它放上github了。 https://github.com/Mirochiu/CollegeAssignments/tree/master/AesCryptor

Java: 視窗置中的方法

假設JFrame的實體是frame,則可以用下面兩種方法使視窗置中 方法一、利用Toolkit類別取得螢幕大小後,再計算出JFrame中間的位置 java.awt.Dimension scr_size = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); frame.setLocation( (scr_size.width - frame.getWidth()) / 2, (scr_size.height - frame.getHeight()) / 2); 使用這個方法的缺點,是必須要先設定好視窗的寬高屬性,或是仙呼叫pack方法自動設定,否則就沒辦法使視窗顯示在螢幕中央。 方法二、利用JFrame的其中一個方法 frame.setLocationRelativeTo(null); 這個方法我還是頭一次知道,而且這方法還不是新的API所增加的,在Java Document 1.4中久已經有描述, JFrame.setLocationRelativeTo(Component) ,只要將參數給null值,就可以使視窗置中,而且 Java Tutorial 也有提到用這個方法。

Java: 反鋸齒繪圖 Paint with graphics using anti-aliasing

圖片
大一的時候寫小遊戲時,發現Java顯示出來的大型中文字怎麼都不甚美觀,文字邊會有鋸齒狀,應該像遊戲一樣要 anti aliasing 一下才對嘛?可是到底要怎麼用,當時就沒繼續研究下去,直到今天才無在 小範例 中發現到它,都過這麼久了說起來還真是汗顏。 實際效果 範例程式碼 import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import javax.swing.JPanel; import javax.swing.JFrame; public class UnicodeText { public static void main(String[] args) { JFrame frm = new JFrame("反鋸齒效果 demo"); JPanel jpn = new JPanel(){ public void paint(Graphics g) { super.paint(g); Graphics2D g2 = (Graphics2D) g; Font Anit = new Font("Monospace", Font.PLAIN, 62); g2.setFont(Anit); g2.drawString("沒用反鋸齒!!", 10, 50); Graphics2D g2d = (Graphics2D)g; g2d.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.drawString("使用反鋸齒!!", 10, 145); } }; frm.add(jpn); frm.setSize(350,200); frm.setResizable(false); frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frm.setVisible(true); } } 重要的就只是兩行,將Graphics強制轉成Graphics2D,...

Java Sinppets:CharacterLimitedTextField

package org.tedluxd.mirror.javaplus; import java.awt.BorderLayout; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JTextField; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.DefaultStyledDocument; /** * 此TextField可限制輸入的字數。 * * @author Mirror Chiu * @last-revise 2008-04-19 */ public class CharacterLimitedTextField extends JTextField { /** * 以指定的欄位寬度與可輸入字元數量,建立含有指定字串的TextField * @param text 字串。 * @param columns 欄位寬度與可輸入字元數量。 * @param limit 欄位寬度與可輸入字元數量。 */ public CharacterLimitedTextField(String text, int columns, int limit) { super(new CharacterLimitedDocument(limit), text, columns); } /** * 以指定的欄位寬度與可輸入字元數量,建立TextField物件。 * * @param columns 欄位寬度。 * @param limit 可輸入字元數量。 */ public CharacterLimitedTextField(int columns, int limit) { super(new CharacterLimitedDocument(limit),null, columns); } /** ...

注意事項:使用getResource產生的URL作為讀取Jar內檔案的圖檔

1. URL要使用正斜線(/)作為目錄分隔 URL使用正斜線作為目錄分隔,所以若是用反斜線就會被當作名稱的一部份,這個問題會出現在Windows系統上,因為Windows是使用反斜線\作為目錄分隔符號。 若是使用反斜線, 在執行class時,URL會交由檔案系統解析,所以就「可能」讀取到圖檔(實際上我救是讀的到)。 但是執行jar時,URL是給URL相關的解析器,所以就把反斜線當作名稱的一部份,也就會找不到jar中圖片檔案。 2. 路徑上不要有驚嘆號(!) 在URL路徑中千萬不要包含驚嘆號(!) 因為這個符號是用來辨別jar檔案內的檔案用的,如果你取一個專案的資料夾名稱為 foo!! ,並將你的程式碼或jar放在裡面,你將會發現,執行jar檔案就是會發生錯誤,會說找不到檔案,但是當你把jar檔案移到一個不包含驚嘆號的目錄後,他就可以正常執行了。 因為在執行class時的URL列印出來是長這樣子 file:/{路徑名稱}/foo!!/foo.class/{圖片路徑} 而執行jar檔案時,URL列印出來會是這個樣子 jar:file:/{路徑名稱}/foo!!/foo.jar!/{圖片路徑} 今天遭遇了第二個問題,又讓我搞了一陣子 JarImageFetcher 。

Java:Create .DLL file in VC++ for JNI

圖片
這篇將指引該如何從Java開始,到利用Visual C++ 2005,建立JNI使用的DLL動態連結函式庫。 首先,要先寫好一個使用JNI的Java程式,這裡以JniExample.java作為範例,程式碼如下。 1. 由java撰寫開始 public class JniExample {   // 主程式   public static void main(String[] args) {     JavaClassWithNativeMethod j =         new JavaClassWithNativeMethod( );     String[] strs = new String[]{"apple","banana","class"};     // 呼叫原生方法     boolean b = j.useNativeMethod(strs);     if (b == true)       System.out.println("Java:All ok, return true.");     else       System.out.println("Java:Somthing wrong, return false.");   } } class JavaClassWithNativeMethod {   // 載入所使用的DLL檔案   static {     System.loadLibrary("MyDLL");     System.out.println("Java:Loading dll is compelete.");   }   public JavaClassWithNativeMethod() {     System.out.println("Java:A new instance created");   }   // 使用JNI的Method,具有native修飾子並且Method為空   public native boolean useNativeMethod(String[] println); } 接著...

Java Puzzlers: 38.The Unwelcome Guest

下面這段程式碼有沒有問題呢? public class UnwelcomeGuest {  public static final long GUEST_USER_ID = -1;  private static final long USER_ID;  static {   try {    USER_ID = getUserIdFromEnvironment();   } catch (IdUnavailableException e) {    USER_ID = GUEST_USER_ID;    System.out.println("Logging in as guest");   }  }  private static long getUserIdFromEnvironment()   throws IdUnavailableException {   throws new IdUnavailableException ();  }   public static void main(String[] args) {   System.out.println("User ID: " + USER_ID);  } } class IdUnavailableException extends Exception {  IdUnavailableException() {  } } 結果:這隻程式看似正常,實際上卻無法編譯! 這是因為要利用電腦來要判斷blank final是否在程式中被設定超過一次是極為困難的, Java編譯器使用的規則是『blank final只有在"當然"未被設定時,才能被設定』。 問題就是只能歸咎於,編譯器的演算法還不夠完善, Java為了安全起見,要求我們必須修改這個不夠安全的程式碼。

Java筆記:SimpleDateFormat的ParseException

圖片
緣由 我有一個「Jul 11 2006」格式的時間字串,想要將它parse進程式中。 從Java Doc中我找到能夠輕易達到功能的方法,就是利用 SimpleDateFormat 來 parse這個字串,然而它卻產生了ParseException,顯然就是不接受我所餵給他的pasre的字串。 程式碼 import java.text.*; import java.util.*; class test {  public static void main(String[] args) {   String date = "Jul 11 2006";   try {    SimpleDateFormat source =     new SimpleDateFormat("MMM dd yyyy");    System.out.println(source.parse(date));   } catch (Exception e) {    e.printStackTrace();   }  } } 在文件中的Date and Time Patterns段落,有寫道使用M是可以parse月份的,且支援 July 、 Jul 、 07三種格式,只是若我們寫1或2個M,就只會當作數字格式,3個以上(含)M之後才會用其他的格式來parse,而程式碼也沒有錯,究竟是怎麼一回事? 在我反覆測試後,我決定再看看Java Doc,撇見含有Locale的建構子,就想到Java Puzzlers,雖然我從來沒有重視過Locale的問題,但是這次就該是Locale的問題,果不其然,設定為英語系後果然就正常運行了(汗) 修正後程式碼 import java.text.*; import java.util.*; class test {   public static void main(String[] args) {   String date = "Jul 11 2006";   try {    SimpleDateFormat source =     new SimpleDateFormat("MMM dd yyyy", Locale.ENGLISH );    System.out.p...

Java小程式:JarImageFetcher

之前使用Eclipse幫高中同學改一隻他們要交的小遊戲時,就覺得很狐疑,為甚麼用class跑就可讀曲到圖片,將它們包成jar檔案就不能用,我明明是用與以前放在jar裡可以跑的程式碼呀? 後來才發現,原來是我沒有把Java-doc看完,在 ClassLoader的getResource 方法中寫了一段註記 The name of a resource is a ' / '-separated path name that identifies the resource. 譯:資源的名稱是以'/'(正斜線)作為區分的的路徑名稱。 在windows上,若不以正斜線作分隔,直接執行class檔,是可以抓到所需的資源;但是,若將所有的資源都包成Jar後,就會抓不到所需的資源了。這也是造成我程式問題,若沒有細看這些註記,實在很難發現問題點。 觀看JarImageFetcher的 完整原始碼。