JLabel'de köprü nasıl eklenir?


Yanıtlar:


96

Bunu a kullanarak yapabilirsiniz JLabel, ancak alternatif bir stil a olabilir JButton. Bu şekilde, erişilebilirlik konusunda endişelenmenize gerek kalmaz ve yalnızca bir ActionListener.

  public static void main(String[] args) throws URISyntaxException {
    final URI uri = new URI("http://java.sun.com");
    class OpenUrlAction implements ActionListener {
      @Override public void actionPerformed(ActionEvent e) {
        open(uri);
      }
    }
    JFrame frame = new JFrame("Links");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(100, 400);
    Container container = frame.getContentPane();
    container.setLayout(new GridBagLayout());
    JButton button = new JButton();
    button.setText("<HTML>Click the <FONT color=\"#000099\"><U>link</U></FONT>"
        + " to go to the Java website.</HTML>");
    button.setHorizontalAlignment(SwingConstants.LEFT);
    button.setBorderPainted(false);
    button.setOpaque(false);
    button.setBackground(Color.WHITE);
    button.setToolTipText(uri.toString());
    button.addActionListener(new OpenUrlAction());
    container.add(button);
    frame.setVisible(true);
  }

  private static void open(URI uri) {
    if (Desktop.isDesktopSupported()) {
      try {
        Desktop.getDesktop().browse(uri);
      } catch (IOException e) { /* TODO: error handling */ }
    } else { /* TODO: error handling */ }
  }

2
+1 Alternatif JTextFieldolarak, bu cevapta gösterildiği gibi a kullanın .
Andrew Thompson

2
Bağlantının parçası olmayan metin bile tıklanarak bağlantıyı takip edebilir.
nöralmer

28

Yine başka bir çözüm önermek istiyorum. Bir JLabel'de HTML kodu kullandığı ve üzerine bir MouseListener kaydettiği için halihazırda önerilenlere benzer, ancak fareyi bağlantının üzerine getirdiğinizde bir El İmleci görüntüler, böylece görünüm ve his çoğu kullanıcının beklediği gibi olur. . Tarama platform tarafından desteklenmiyorsa, kullanıcıyı yanıltabilecek mavi, altı çizili HTML bağlantısı oluşturulmaz. Bunun yerine, bağlantı yalnızca düz metin olarak sunulur. Bu, @ dimo414 tarafından önerilen SwingLink sınıfı ile birleştirilebilir.

public class JLabelLink extends JFrame {

private static final String LABEL_TEXT = "For further information visit:";
private static final String A_VALID_LINK = "http://stackoverflow.com";
private static final String A_HREF = "<a href=\"";
private static final String HREF_CLOSED = "\">";
private static final String HREF_END = "</a>";
private static final String HTML = "<html>";
private static final String HTML_END = "</html>";

public JLabelLink() {
    setTitle("HTML link via a JLabel");
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

    Container contentPane = getContentPane();
    contentPane.setLayout(new FlowLayout(FlowLayout.LEFT));

    JLabel label = new JLabel(LABEL_TEXT);
    contentPane.add(label);

    label = new JLabel(A_VALID_LINK);
    contentPane.add(label);
    if (isBrowsingSupported()) {
        makeLinkable(label, new LinkMouseListener());
    }

    pack();
}

private static void makeLinkable(JLabel c, MouseListener ml) {
    assert ml != null;
    c.setText(htmlIfy(linkIfy(c.getText())));
    c.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
    c.addMouseListener(ml);
}

private static boolean isBrowsingSupported() {
    if (!Desktop.isDesktopSupported()) {
        return false;
    }
    boolean result = false;
    Desktop desktop = java.awt.Desktop.getDesktop();
    if (desktop.isSupported(Desktop.Action.BROWSE)) {
        result = true;
    }
    return result;

}

private static class LinkMouseListener extends MouseAdapter {

    @Override
    public void mouseClicked(java.awt.event.MouseEvent evt) {
        JLabel l = (JLabel) evt.getSource();
        try {
            URI uri = new java.net.URI(JLabelLink.getPlainLink(l.getText()));
            (new LinkRunner(uri)).execute();
        } catch (URISyntaxException use) {
            throw new AssertionError(use + ": " + l.getText()); //NOI18N
        }
    }
}

private static class LinkRunner extends SwingWorker<Void, Void> {

    private final URI uri;

    private LinkRunner(URI u) {
        if (u == null) {
            throw new NullPointerException();
        }
        uri = u;
    }

    @Override
    protected Void doInBackground() throws Exception {
        Desktop desktop = java.awt.Desktop.getDesktop();
        desktop.browse(uri);
        return null;
    }

    @Override
    protected void done() {
        try {
            get();
        } catch (ExecutionException ee) {
            handleException(uri, ee);
        } catch (InterruptedException ie) {
            handleException(uri, ie);
        }
    }

    private static void handleException(URI u, Exception e) {
        JOptionPane.showMessageDialog(null, "Sorry, a problem occurred while trying to open this link in your system's standard browser.", "A problem occured", JOptionPane.ERROR_MESSAGE);
    }
}

private static String getPlainLink(String s) {
    return s.substring(s.indexOf(A_HREF) + A_HREF.length(), s.indexOf(HREF_CLOSED));
}

//WARNING
//This method requires that s is a plain string that requires
//no further escaping
private static String linkIfy(String s) {
    return A_HREF.concat(s).concat(HREF_CLOSED).concat(s).concat(HREF_END);
}

//WARNING
//This method requires that s is a plain string that requires
//no further escaping
private static String htmlIfy(String s) {
    return HTML.concat(s).concat(HTML_END);
}

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            new JLabelLink().setVisible(true);
        }
    });
}
}

1
EDT'de bağlantı yapmamak mükemmel bir yakalama! SwingX HyperlinkAction'ı da düzeltmemesi için düzeltmeniz gerekiyor :-)
kleopatra

SwingX'te bir sorun açtı: java.net/jira/browse/SWINGX-1530 - bunu gündeme getirdiğin için teşekkürler :-)
kleopatra

@kleopatra Rica ederim :) Desktop.browse'ın engelleme davranışını yeniden oluşturamadınız gibi görünüyor - yavaş makinemde kesinlikle engelliyor, özellikle de tarayıcı henüz açık değilse.
Stefan

iyi bir nokta! yorumunuzu konuya ekledi - neredeyse düzeltilmeyeceği için kapanma eğilimindeydi, yorumunuz beni kurtardı :-)
kleopatra

Bu ilginç bir çözüm. JLabel'i nasıl genişlettiğini seviyorum - bu, GroupLayout'un onu bir düğme gibi değil, bir etiket gibi konumlandırma olasılığının daha yüksek olduğu anlamına geliyor. Düğmeleri kullanmanın bileşenler arasındaki mesafeyi artırdığını fark ettim ...
Trejkaz

17

Bir jLabel üzerinde köprü veya mailto'nun nasıl ayarlanacağına dair bir makale yazdım.

Dolayısıyla, sadece denemek o :

Sanırım tam olarak aradığınız şey bu.

İşte tam kod örneği:

/**
 * Example of a jLabel Hyperlink and a jLabel Mailto
 */

import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
 *
 * @author ibrabelware
 */
public class JLabelLink extends JFrame {
    private JPanel pan;
    private JLabel contact;
        private JLabel website;
    /**
     * Creates new form JLabelLink
     */
    public JLabelLink() {
        this.setTitle("jLabelLinkExample");
        this.setSize(300, 100);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);

        pan = new JPanel();
        contact = new JLabel();
        website = new JLabel();

        contact.setText("<html> contact : <a href=\"\">YourEmailAddress@gmail.com</a></html>");
        contact.setCursor(new Cursor(Cursor.HAND_CURSOR));

        website.setText("<html> Website : <a href=\"\">http://www.google.com/</a></html>");
        website.setCursor(new Cursor(Cursor.HAND_CURSOR));

    pan.add(contact);
    pan.add(website);
        this.setContentPane(pan);
        this.setVisible(true);
        sendMail(contact);
        goWebsite(website);
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /*
         * Create and display the form
         */
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new JLabelLink().setVisible(true);
            }
        });
    }

    private void goWebsite(JLabel website) {
        website.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                try {
                    Desktop.getDesktop().browse(new URI("http://www.google.com/webhp?nomo=1&hl=fr"));
                } catch (URISyntaxException | IOException ex) {
                    //It looks like there's a problem
                }
            }
        });
    }

    private void sendMail(JLabel contact) {
        contact.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                try {
                    Desktop.getDesktop().mail(new URI("mailto:YourEmailAddress@gmail.com?subject=TEST"));
                } catch (URISyntaxException | IOException ex) {
                    //It looks like there's a problem
                }
            }
        });
    }
}

15

GüncellemeSwingLink Sınıfı daha da derledim ve daha fazla özellik ekledim; güncel bir kopyası burada bulunabilir: https://bitbucket.org/dimo414/jgrep/src/tip/src/grep/SwingLink.java


@ McDowell'in cevabı harika, ancak geliştirilebilecek birkaç şey var. Özellikle köprü dışındaki metin tıklanabilir ve stilin bir kısmı değiştirilmiş / gizlenmiş olsa bile yine de bir düğme gibi görünüyor. Erişilebilirlik önemli olsa da tutarlı bir kullanıcı arayüzü de önemlidir.

Bu yüzden McDowell'in kodunu temel alan JLabel'i genişleten bir sınıf oluşturdum. Bağımsızdır, hataları düzgün bir şekilde ele alır ve daha çok bir bağlantı gibi hisseder:

public class SwingLink extends JLabel {
  private static final long serialVersionUID = 8273875024682878518L;
  private String text;
  private URI uri;

  public SwingLink(String text, URI uri){
    super();
    setup(text,uri);
  }

  public SwingLink(String text, String uri){
    super();
    setup(text,URI.create(uri));
  }

  public void setup(String t, URI u){
    text = t;
    uri = u;
    setText(text);
    setToolTipText(uri.toString());
    addMouseListener(new MouseAdapter() {
      public void mouseClicked(MouseEvent e) {
        open(uri);
      }
      public void mouseEntered(MouseEvent e) {
        setText(text,false);
      }
      public void mouseExited(MouseEvent e) {
        setText(text,true);
      }
    });
  }

  @Override
  public void setText(String text){
    setText(text,true);
  }

  public void setText(String text, boolean ul){
    String link = ul ? "<u>"+text+"</u>" : text;
    super.setText("<html><span style=\"color: #000099;\">"+
    link+"</span></html>");
    this.text = text;
  }

  public String getRawText(){
    return text;
  }

  private static void open(URI uri) {
    if (Desktop.isDesktopSupported()) {
      Desktop desktop = Desktop.getDesktop();
      try {
        desktop.browse(uri);
      } catch (IOException e) {
        JOptionPane.showMessageDialog(null,
            "Failed to launch the link, your computer is likely misconfigured.",
            "Cannot Launch Link",JOptionPane.WARNING_MESSAGE);
      }
    } else {
      JOptionPane.showMessageDialog(null,
          "Java is not able to launch links on your computer.",
          "Cannot Launch Link", JOptionPane.WARNING_MESSAGE);
    }
  }
}

Ayrıca, yararlı görünüyorsa, örneğin, tıklandıktan sonra bağlantı rengini mora değiştirebilirsiniz. Hepsi kendi kendine yeten, basitçe şunu arayın:

SwingLink link = new SwingLink("Java", "http://java.sun.com");
mainPanel.add(link);

1
Uri

Fare bir ele dönüşürse, daha da iyi olur!
Leon

@Leon cevabımın en üstünde bağlantılı versiyona bir göz atın, setCursor(new Cursor(Cursor.HAND_CURSOR));bu cevapta varyant satır içi üzerinde başka geliştirmeler kullanıyor ve var.
dimo414


13

JLabel yerine JEditorPane kullanmayı deneyebilirsiniz. Bu, temel HTML'yi anlar ve JEditPane ile kaydettiğiniz HyperlinkListener'a bir HyperlinkEvent olayı gönderir.


1
İçinde bazı köprüler bulunan metinleriniz varsa (muhtemelen anında değiştirilmiş) bu en iyi çözümdür. Diğer çözümlerin çoğu, köprünün ayrı bir denetime yerleştirilmesini gerektirir.
user149408

5

<a href="link"> çalışmazsa, o zaman:

  1. Bir JLabel oluşturun ve bir MouseListener ekleyin (etiketi bir köprü gibi görünecek şekilde dekore edin)
  2. Uygulama mouseClicked () olay
  3. MouseClicked () olayının uygulanmasında, eyleminizi gerçekleştirin

Varsayılan tarayıcıyı kullanarak bir bağlantı açmak için java.awt.Desktop API'ye bir göz atın (bu API yalnızca Java6'da mevcuttur).


4

Partiye biraz geç kaldığımı biliyorum ama başkalarının havalı / yararlı bulabileceği küçük bir yöntem geliştirdim.

public static JLabel linkify(final String text, String URL, String toolTip)
{
    URI temp = null;
    try
    {
        temp = new URI(URL);
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
    final URI uri = temp;
    final JLabel link = new JLabel();
    link.setText("<HTML><FONT color=\"#000099\">"+text+"</FONT></HTML>");
    if(!toolTip.equals(""))
        link.setToolTipText(toolTip);
    link.setCursor(new Cursor(Cursor.HAND_CURSOR));
    link.addMouseListener(new MouseListener()
    {
        public void mouseExited(MouseEvent arg0)
        {
            link.setText("<HTML><FONT color=\"#000099\">"+text+"</FONT></HTML>");
        }

        public void mouseEntered(MouseEvent arg0)
        {
            link.setText("<HTML><FONT color=\"#000099\"><U>"+text+"</U></FONT></HTML>");
        }

        public void mouseClicked(MouseEvent arg0)
        {
            if (Desktop.isDesktopSupported())
            {
                try
                {
                    Desktop.getDesktop().browse(uri);
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
            else
            {
                JOptionPane pane = new JOptionPane("Could not open link.");
                JDialog dialog = pane.createDialog(new JFrame(), "");
                dialog.setVisible(true);
            }
        }

        public void mousePressed(MouseEvent e)
        {
        }

        public void mouseReleased(MouseEvent e)
        {
        }
    });
    return link;
}

Size uygun bir bağlantı gibi davranan bir JLabel verecektir.

Eylemde:

public static void main(String[] args)
{
    JFrame frame = new JFrame("Linkify Test");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400, 100);
    frame.setLocationRelativeTo(null);
    Container container = frame.getContentPane();
    container.setLayout(new GridBagLayout());
    container.add(new JLabel("Click "));
    container.add(linkify("this", "http://facebook.com", "Facebook"));
    container.add(new JLabel(" link to open Facebook."));
    frame.setVisible(true);
}

Hiçbir ipucu istemiyorsanız, sadece boş bir değer gönderin.

Umarım birisi bunu faydalı bulur! (Eğer yaparsanız, bana haber verdiğinizden emin olun, duymaktan mutluluk duyarım.)


4

Bir JEditorPaneile a kullanın HyperlinkListener.


1

Sadece söylemek gerekirse window.open(website url), her seferinde işe yarar.


1

Aşağıdaki kodun JHyperLinkoluşturma yolunuza eklenmesi gerekir.

JHyperlink stackOverflow = new JHyperlink("Click HERE!",
                "https://www.stackoverflow.com/");

JComponent[] messageComponents = new JComponent[] { stackOverflow };

JOptionPane.showMessageDialog(null, messageComponents, "StackOverflow",
                JOptionPane.PLAIN_MESSAGE);

JComponentDiziyi daha fazla Swingbileşenle doldurabileceğinizi unutmayın .

Sonuç:


0

Bunu bir altında kullanabilirsiniz

actionListener ->  Runtime.getRuntime().exec("cmd.exe /c start chrome www.google.com")`

Kullanmak istediğiniz takdirde veya Internet Explorer veya Firefox yerini chromeile iexploreveyafirefox

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.