2015-05-29 101 views
-1

我在Java中創建一個類來表示字符串和顏色,稱爲ColoredString。我希望能夠使用.Net框架識別的任何顏色的顏色名稱創建這些對象中的一個。這樣的顏色列表在這裏:http://www.simplehtmlguide.com/colours.php。由於Java沒有包含「已知顏色」的全面列表,我的解決方案是讓我的程序從文件中讀取以填充使用的已知顏色列表。所以,我提出以下格式的文本文件:靜態變量初始化從一個文件初始化一次

AliceBlue #F0F8FF 
AntiqueWhite #FAEBD7 
Aqua #00FFFF 
Aquamarine #7FFFD4 

第一個字是顏色名,第二個是在格式#RRGGBB指定顏色代碼。由於我顯然不希望每次調用ColoredString的構造函數時都要從文件中讀取數據,所以我想我可能會將它讀入靜態變量中,希望當我的程序運行時,該文件將被讀取一次並創建這個靜態變量的一個實例可以被任何一個ColoredString實例引用。下面是我寫這樣做代碼:

import java.awt.Color; 
import java.io.File; 
import java.io.FileNotFoundException; 
import java.util.ArrayList; 
import java.util.Scanner; 

public class ColoredString { 

    public static final ArrayList<KnownColor> knownColors = setKCs(); 

    private static ArrayList<KnownColor> setKCs() { 
     try (Scanner scanner = new Scanner(new File("dotNet_knownColors.txt"));) { 
      ArrayList<KnownColor> knownColors = new ArrayList<>(); 
      while (scanner.hasNextLine()) { 
       String colorName = scanner.next().toLowerCase(); 
       String colorCode = scanner.next().toUpperCase(); 
       knownColors.add(new KnownColor(colorName, colorCode)); 
      } 
      return knownColors; 
     } catch (FileNotFoundException fnfex) { 
      System.out.println("uh-oh..."); 
     } 
     return null; 
    } 
    public static final String defaultColor = "black"; 
    private Color color; 
    private String string; 

    public ColoredString(String color, String string) { 
     if (color == null || color.equals("")) { 
      color = defaultColor; 
     } 
     color = color.toLowerCase(); 
     this.string = string; 
     if (color.startsWith("#")) { 
      this.color = new Color(Integer.parseInt(color.substring(1), 16)); 
     } else { 
      this.color = getColorByName(color); 
     } 
    } 

    public ColoredString(String string) { 
     this.string = string; 
     this.color = getColorByName(defaultColor);//default color 

    } 

    private static Color getColorByName(String name) { 
     for (KnownColor c : knownColors) { 
      if (c.name.equals(name)) { 
       String colorCode = c.rgbHexNum; 
       return new Color(Integer.parseInt(colorCode.substring(1), 16)); 
      } 
     } 
     return getColorByName(defaultColor); 
    } 

    private static class KnownColor { 

     public final String name; 
     public final String rgbHexNum; 

     public KnownColor(String name, String rgbHexNum) { 
      this.name = name; 
      this.rgbHexNum = rgbHexNum; 
     } 
    } 
} 

所以我的問題是這樣的:將我的代碼做正如我所說,並從文件只讀一次,並只創建變量knownColors的單個實例,甚至如果我創建了我的課程的許多實例?

+1

你測試了嗎?添加一些'println()',它會告訴你。另外,你可能對'static {...}'(靜態初始化塊)感興趣。 –

+0

首先初始化靜態變量,在調用任何'new'運算符之前,一個靜態變量有一個實例,所以回答最後一個問題是肯定的。 – itwasntme

+0

@QPaysTaxes,謝謝。這是初始化我的變量更簡單的方法。我以前不知道靜態初始化塊。 –

回答

0

首先檢查Java。下面是java 8;並且我使用javafx.scene.paint.Color,因爲Oracle認爲JavaFX是AWT/Swing的繼任者。

它可以做148個顏色名稱。

首先在你的顏色測試:

String[] colorNames = { "aquamarine", "Aquamarine", "AntiqueWhite" }; 
    // List with color as hex, with alpha component as FF 
    for (String colorName : colorNames) { 
     Color color = Color.valueOf(colorName); 
     System.out.printf("%s -> %s%n", colorName, color); 
    } 

然後,所有顏色常量:

for (Field field : Color.class.getDeclaredFields()) { 
     int modifiers = field.getModifiers(); 
     if (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers) 
       && Modifier.isFinal(modifiers) && field.getType() == Color.class) { 
      String colorName = field.getName().toLowerCase(Locale.US); 
      Color color = Color.valueOf(colorName); 
      System.out.printf("- %s -> %s%n", colorName, color); 
     } 
    } 

本使用反射,並假定常量名是人類可讀的名字。

[139] thistle -> 0xd8bfd8ff 
[140] tomato -> 0xff6347ff 
[141] turquoise -> 0x40e0d0ff 
[142] violet -> 0xee82eeff 
[143] wheat -> 0xf5deb3ff 
[144] white -> 0xffffffff 
[145] whitesmoke -> 0xf5f5f5ff 
[146] yellow -> 0xffff00ff 
[147] yellowgreen -> 0x9acd32ff 
1

從簡單的看...是的。

如果您想確定,爲什麼不用代碼中的斷點來調試程序,並從文件中加載代碼並查看它被多次擊中?或者暫時在System.out.println中添加一些代碼。

+0

是的,完全正確。只有一個knownColors實例將被創建:) –