2012-09-14 25 views
6

मुझे लगता है कि, काम करता है अन्य लोगों के बीच एक जावा डेस्कटॉप ऐप्लिकेशन मिल गया है, ओएस एक्सघुमाओ और रेटिना पर बिटमैप को प्रदर्शित करता है

पर अब नए मैकबुक प्रो एक रेटिना डिस्प्ले है और मेरा सवाल है: यह कैसे हो रहा है स्विंग के बारे में काम करने के लिए?

जब जावा ऐप स्विंग घटकों और कुछ बिटमैप ग्राफिक्स (जैसे कस्टम आइकन/छवि आइकन) दोनों का उपयोग करता है तो क्या होगा?

क्या सभी डेस्कटॉप जावा ऐप्स स्वचालित रूप से आकार बदल जाएंगे (उदाहरण के लिए प्रत्येक पिक्सेल चौगुनी करके) या मुझे अपने आइकन सेट के दो संस्करण बनाने की आवश्यकता होगी (उदाहरण के लिए 24x24 आइकन और दूसरा 96x96 आइकन के साथ) और किसी भी तरह यह निर्धारित करें कि ऐप रेटिना डिस्प्ले पर चल रहा है?

+3

कृपया एक प्रश्न [एसएससीई] (http://sscce.org/) शामिल करने के लिए अपना प्रश्न संपादित करें जो आपके चिंता का क्षेत्र दिखाता है; एक नया मैकबुक प्रो रेटिना डिस्प्ले स्वामी एक [स्क्रीनशॉट] पोस्ट कर सकता है (http://meta.stackexchange.com/questions/99734/how-do-i-create-a-creenshot-to-illustrate-a-post)। – trashgod

+0

बीटीडब्ल्यू, आपका 24x24 आइकन केवल 48x48 आइकन बनने की जरूरत है। रेटिना प्रत्येक आयाम में संकल्प को दोगुना करता है, जो प्रत्येक पिक्सेल को चार पिक्सेल में बदल देता है। – MiguelMunoz

उत्तर

0

यह माउस मेरी रेटिना मैकबुक '12 पर की तरह लग रही है कि कैसे:

enter image description here

IntelliJ विचार 11 (स्विंग एप्लिकेशन) में बाईं ओर माउस पर और दाईं ओर आईडिया 12 जो होने का दावा किया जाता है पर को पुन: स्थापित किया गया। जैसा कि आप स्वचालित रूप से आकार बदल सकते हैं आइकन (बाईं ओर) बहुत बदसूरत लग रहा है।

जहां तक ​​मुझे पता है, वे just like the guys from Chrome team, इसे डबल आकार के आइकन प्रदान करके बना दिया।

4

ऐप्पल के जावा 6 पर आप एक ही छवि के कई संस्करण प्रदान कर सकते हैं। स्क्रीन (रेटिना या नहीं) के आधार पर, एक या दूसरी छवि को उठाया और खींचा जाता है।

हालांकि, उन छवियों को एक विशेष तरीके से लोड करने के लिए है:

Toolkit.getDefaultToolkit().getImage("NSImage://your_image_name_without_extension"); 

उदाहरण के लिए, यदि आपके (नियमित संकल्प) छवि कहा जाता है: "scissor.png", आप एक उच्च संकल्प संस्करण बनाने के लिए है "[email protected]" (Apple naming conventions के बाद) और अपने ऐप बंडल की Resources निर्देशिका में दोनों छवियां रखें (हां, आपको bundle your app की आवश्यकता है)। फिर फोन:

Image img = Toolkit.getDefaultToolkit().getImage("NSImage://scissor"); 

आप अपने बटन में जिसके परिणामस्वरूप छवि का उपयोग कर सकते हैं और यह सही संकल्प जादुई साथ तैयार किया जाएगा।

दो अन्य "चाल" कर रहे हैं आप का उपयोग कर सकते हैं:

  1. एक छवि निकालने से पहले (0.5, 0.5) अपने Graphics2D वस्तु पर का एक AffineTransform का उपयोग करना। यह भी देखें this java-dev message
  2. प्रोग्राम के रूप में अब भी Oracle के जावा 7/8 पर काम करता है द्वारा this hack

पहले "चाल" (0.5 स्केलिंग) का उपयोग कर अपनी छवि के एक उच्च डीपीआई संस्करण बना रहा है। आईई। यदि आप सीधे घटक के ग्राफ़िक्स ऑब्जेक्ट पर 0.5 स्केलिंग वाली छवि खींचते हैं, तो इसे रेटिना डिस्प्ले पर उच्च रिज़ॉल्यूशन में प्रस्तुत किया जाएगा (और इसके आधे आकार के आधे से भी)।

+0

उत्तरदाता के अलावा कोई अन्य व्यक्ति कृपया इसे वोट दे सकता है या अगर यह वास्तव में काम करता है तो इसे स्वीकार कर सकता है, यह तब तक इस प्रश्न के विरुद्ध डुप्लीकेट बंद करना संभव नहीं है जब तक यह नहीं किया जाता है। –

7

IconLoader लाइब्रेरी का उपयोग करें। यह HiDPI छवियों का समर्थन करता है http://bulenkov.com/iconloader/ यह HiDPI छवियों (ड्राइंग, आदि) के साथ काम करने का एक तरीका भी प्रदान करता है

1

मैं पुष्टि कर सकता हूं कि आपकी छवियां ओरेकल जावा 1.8 पर स्केलिंग करती हैं। मुझे जावा 1.7 या 1.8 पर काम करने के लिए NSImage हैक नहीं मिल सकता है।मैं मैक से लगता है कि जावा 6 के साथ यह केवल काम करता है ...

जब तक किसी और एक बेहतर समाधान है, मैं क्या निम्नलिखित है:

माउस के दो सेट बनाएँ। यदि आपके पास 48pixel चौड़ाई आइकन है 48px @ सामान्य DPI और 96px पर 2x DPI के साथ। सेब नामकरण मानकों के अनुरूप के रूप में 2xDPI छवि का नाम बदलें।

सबक्लास ImageIcon और इसे RetinaIcon या जो कुछ भी कहें। आप एक रेटिना प्रदर्शन के लिए परीक्षण कर सकते हैं इस प्रकार है:

public static boolean isRetina() { 

boolean isRetina = false; 
GraphicsDevice graphicsDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); 

try { 
       Field field = graphicsDevice.getClass().getDeclaredField("scale"); 
     if (field != null) { 
      field.setAccessible(true); 
      Object scale = field.get(graphicsDevice); 
      if(scale instanceof Integer && ((Integer) scale).intValue() == 2) { 
       isRetina = true; 
      } 
     } 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return isRetina; 
} 

इस प्रकार सुनिश्चित करें @Override के लिए चौड़ाई और नए ImageIcon वर्ग की ऊंचाई करें:

@Override 
public int getIconWidth() 
{ 
    if(isRetina()) 
    { 
     return super.getIconWidth()/2; 
    } 
    return super.getIconWidth(); 
} 

@Override 
public int getIconHeight() 
{ 
    if(isRetina()) 
    { 
     return super.getIconHeight()/2; 
    } 
    return super.getIconHeight(); 
} 

एक बार जब आप रेटिना स्क्रीन के लिए एक परीक्षण है

@Override 
public synchronized void paintIcon(Component c, Graphics g, int x, int y) 
{ 
    ImageObserver observer = getImageObserver(); 

    if (observer == null) 
    { 
     observer = c; 
    } 

    Image image = getImage(); 
    int width = image.getWidth(observer); 
    int height = image.getHeight(observer); 
    final Graphics2D g2d = (Graphics2D)g.create(x, y, width, height); 

    if(isRetina()) 
    { 
     g2d.scale(0.5, 0.5); 
    } 
    else 
    { 

    } 
    g2d.drawImage(image, 0, 0, observer); 
    g2d.scale(1, 1); 
    g2d.dispose(); 
} 

मैं: और अपने कस्टम चौड़ाई/ऊंचाई तरीके इस प्रकार आप painIcon विधि अनुकूलित कर सकते हैं अधिरोहित यह नहीं पता कि यह एकाधिक स्क्रीन के साथ कैसे काम करेगा- क्या कोई और है जो उसमें मदद कर सकता है ???

आशा है कि यह कोड वैसे भी मदद करेगा!

जेसन बैराक्लो। RetinaIcon is on the left. ImageIcon is on the right

+0

इस समाधान के लिए धन्यवाद। यह अच्छी तरह से काम करता है। – user3396583

0

यहाँ एक समाधान है, वह भी काम करता है जब माउस सेब मेनू में उपयोग किया जाता है:

यहाँ जैसा कि ऊपर उल्लेख स्केलिंग का उपयोग करने का एक उदाहरण है। वहां आइकन स्वचालित रूप से गहरा हुआ है।

public synchronized void paintIcon(Component c, Graphics g, int x, int y) { 
    if(getImageObserver() == null) { 
     g.drawImage(getImage0(), x, y, getIconWidth(), getIconHeight(), c); 
    } else { 
     g.drawImage(getImage0(), x, y, getIconWidth(), getIconHeight(), getImageObserver()); 
    } 
} 

कैसे पक्का हो जानेवाला मैं अभी तक पता लगा नहीं किया है में हुक करने: तो मैं एक वर्ग DenseIcon जो घनी पेंट लागू किया है। तो एक kludge के रूप में हम एक कम रेस छवि वापस इतना है कि मेनू अपने संशोधनों कर सकते हैं:

public Image getImage() { 
    Image image = getImage0().getScaledInstance(
      getIconWidth(), 
      getIconHeight(), 
      Image.SCALE_SMOOTH); 
    ImageIcon icon = new ImageIcon(image, getDescription()); 
    return icon.getImage(); 
} 

आप gist पर पूर्ण वर्ग यहाँ का कोड पाते हैं। आपको आइकन क्लास को किसी छवि के साथ दो बार आकार देने वाली छवि को तुरंत चालू करने की आवश्यकता है। 2 के डिस्प्ले के लिए काम करता है।