2009-06-10 28 views
9

Tôi muốn hiển thị một cây tệp tương tự như java2s.com 'Create a lazy file tree', nhưng bao gồm các biểu tượng hệ thống thực tế - đặc biệt là cho các thư mục. SWT dường như không cung cấp tính năng này (API chương trình không hỗ trợ thư mục), vì vậy tôi đã đưa ra những điều sau:Làm thế nào để hiển thị biểu tượng hệ thống cho một tệp trong SWT?

public Image getImage(File file) 
{ 
    ImageIcon systemIcon = (ImageIcon) FileSystemView.getFileSystemView().getSystemIcon(file); 
    java.awt.Image image = systemIcon.getImage(); 

    int width = image.getWidth(null); 
    int height = image.getHeight(null); 
    BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 
    Graphics2D g2d = bufferedImage.createGraphics(); 
    g2d.drawImage(image, 0, 0, null); 
    g2d.dispose(); 
    int[] data = ((DataBufferInt) bufferedImage.getData().getDataBuffer()).getData(); 
    ImageData imageData = new ImageData(width, height, 24, new PaletteData(0xFF0000, 0x00FF00, 0x0000FF)); 
    imageData.setPixels(0, 0, data.length, data, 0); 
    Image swtImage = new Image(this.display, imageData); 
    return swtImage; 
} 

Tuy nhiên, các khu vực phải trong suốt được hiển thị bằng màu đen. Làm thế nào để tôi làm việc này, hoặc có cách tiếp cận khác tôi nên thực hiện?

Cập nhật:

Tôi nghĩ lý do là PaletteData không dành cho tính minh bạch ở tất cả.

Hiện tại, tôi điền vào BufferedImage với Color.WHITE ngay bây giờ, đây là giải pháp có thể chấp nhận được. Tuy nhiên, tôi muốn biết giải pháp thực sự ở đây ...

Trả lời

6

Bạn cần một phương pháp như sau, mà là một bản sao 99% so với http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet156.java?view=co:

static ImageData convertToSWT(BufferedImage bufferedImage) { 
    if (bufferedImage.getColorModel() instanceof DirectColorModel) { 
     DirectColorModel colorModel = (DirectColorModel)bufferedImage.getColorModel(); 
     PaletteData palette = new PaletteData(colorModel.getRedMask(), colorModel.getGreenMask(), colorModel.getBlueMask()); 
     ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette); 
     for (int y = 0; y < data.height; y++) { 
      for (int x = 0; x < data.width; x++) { 
       int rgb = bufferedImage.getRGB(x, y); 
       int pixel = palette.getPixel(new RGB((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF)); 
       data.setPixel(x, y, pixel); 
       if (colorModel.hasAlpha()) { 
        data.setAlpha(x, y, (rgb >> 24) & 0xFF); 
       } 
      } 
     } 
     return data;   
    } else if (bufferedImage.getColorModel() instanceof IndexColorModel) { 
     IndexColorModel colorModel = (IndexColorModel)bufferedImage.getColorModel(); 
     int size = colorModel.getMapSize(); 
     byte[] reds = new byte[size]; 
     byte[] greens = new byte[size]; 
     byte[] blues = new byte[size]; 
     colorModel.getReds(reds); 
     colorModel.getGreens(greens); 
     colorModel.getBlues(blues); 
     RGB[] rgbs = new RGB[size]; 
     for (int i = 0; i < rgbs.length; i++) { 
      rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF); 
     } 
     PaletteData palette = new PaletteData(rgbs); 
     ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette); 
     data.transparentPixel = colorModel.getTransparentPixel(); 
     WritableRaster raster = bufferedImage.getRaster(); 
     int[] pixelArray = new int[1]; 
     for (int y = 0; y < data.height; y++) { 
      for (int x = 0; x < data.width; x++) { 
       raster.getPixel(x, y, pixelArray); 
       data.setPixel(x, y, pixelArray[0]); 
      } 
     } 
     return data; 
    } 
    return null; 
} 

Sau đó, bạn có thể gọi nó thích:

static Image getImage(File file) { 
    ImageIcon systemIcon = (ImageIcon) FileSystemView.getFileSystemView().getSystemIcon(file); 
    java.awt.Image image = systemIcon.getImage(); 
    if (image instanceof BufferedImage) { 
     return new Image(display, convertToSWT((BufferedImage)image)); 
    } 
    int width = image.getWidth(null); 
    int height = image.getHeight(null); 
    BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); 
    Graphics2D g2d = bufferedImage.createGraphics(); 
    g2d.drawImage(image, 0, 0, null); 
    g2d.dispose(); 
    return new Image(display, convertToSWT(bufferedImage)); 
} 
+1

Tôi đã đi với cách tiếp cận đó. Tuy nhiên, tôi cảm thấy rất buồn khi bạn phải nhảy qua các vòng như vậy để làm cho nó hoạt động. –

0

Tôi chưa xem mã chi tiết, nhưng tôi nhận thấy bạn đang sử dụng TYPE & # x005f; INT & # x005f; RGB thay vì TYPE_INT_ARGB (bao gồm hỗ trợ alpha/minh bạch).


Nhìn vào Snippet32 trên trang web Eclipse, tôi có thể thấy rằng bạn thường có thể nhận các biểu tượng bằng cách sử dụng lớp Program. Sử dụng tiện ích mở rộng ".Folder" dường như không trả về một phiên bản, mặc dù nó là thành viên của getExtensions().

Mã này có thể nhận được một biểu tượng thư mục:

Display display = new Display(); 
Shell shell = new Shell(display); 
Label label = new Label(shell, SWT.NONE); 
label.setText("Can't find icon"); 
Image image = null; 
for (Program p : Program.getPrograms()) { 
    if ("Folder".equals(p.getName())) { 
    ImageData data = p.getImageData(); 
    if (data != null) { 
     image = new Image(display, data); 
     label.setImage(image); 
    } 
    break; 
    } 
} 
label.pack(); 
shell.pack(); 
shell.open(); 
while (!shell.isDisposed()) { 
    if (!display.readAndDispatch()) 
    display.sleep(); 
} 
if (image != null) 
    image.dispose(); 
display.dispose(); 

Đó là mã cần tinh tế, tôi nghĩ, nhưng phải là một con trỏ đi đúng hướng. Tôi chỉ được thử nghiệm trên Windows XP tiếng Anh.

+0

Chuyển sang TYPE_INT_ARGB không thay đổi bất cứ điều gì. // Tôi không thực sự muốn dùng heuristics để tìm biểu tượng. Điều gì về các loại ổ đĩa, chẳng hạn như đĩa cứng, thẻ nhớ, ổ đĩa DVD, bạn đặt tên cho nó? –

1

Đối với các file, bạn có thể sử dụng org.eclipse.swt.program.Program để có được một biểu tượng (với đúng bộ minh bạch) cho một tập tin được kết thúc:

File file=... 
String fileEnding = file.getName().substring(file.getName().lastIndexOf('.')); 
ImageData iconData=Program.findProgram(fileEnding).getImageData(); 
Image icon= new Image(Display.getCurrent(), iconData); 

Đối với thư mục, bạn có thể cân nhắc chỉ sử dụng một biểu tượng tĩnh.

+0

Không, tôi muốn các biểu tượng thực sự. –

Các vấn đề liên quan