2010-08-20 40 views
6

Trước khi bất kỳ ai đề xuất HTML, tôi giải thích sau tại sao đó không phải là tùy chọn ở đây. Tôi có một bảng có chứa một cột với các ô văn bản trong đó. Tôi cần để có thể làm nổi bật một số văn bản trong mỗi ô. Vì vậy, ví dụ nếu ô chứa "cat foo dog" ... tôi có thể muốn làm nổi bật foo.Làm cách nào để đánh dấu một phần của JLabel?

Phương pháp hiện tại của tôi là sử dụng TableCellRenderer tùy chỉnh để đặt html vào thành phần JLabel được hiển thị và trong một thời gian tốt. Sau đó, tôi nhận thấy rằng khi các văn bản trong các tế bào trở nên quá dài để phù hợp với chiều rộng cột nó chỉ cắt ngắn văn bản mà không có bình thường "..." xảy ra bình thường trong trường hợp này. Vì vậy, người dùng không biết có nhiều văn bản họ không nhìn thấy. Vấn đề khác là nếu bản gốc văn bản chính nó chứa HTML, mà trong trường hợp của tôi nó vào những thời điểm, các tế bào sẽ không hiển thị chính xác. Tôi biết tôi chỉ có thể thoát khỏi html nhưng tôi vẫn sẽ có vấn đề phổ biến.

Nếu tôi sử dụng một thành phần không phải là nhãn ghi thì nó làm cho các ô của bảng trông lạ. Có ai có bất cứ đề nghị? Cảm ơn

Trả lời

7

Vâng, đây là giải pháp.

Tóm lại, bạn có thể phân lớp JLabel để vẽ điểm đánh dấu theo cách thủ công. Ghi đè phương pháp paintComponent để thực hiện bản vẽ và sử dụng thực tế FontMetrics để tính toán vị trí được đánh dấu khu vực.

Dưới đây là câu trả lời một cách chi tiết đớn:

Về cơ bản, bạn có thể làm cho một lớp con của JLabel có thể làm nổi bật thứ. Tôi sẽ làm điều đó như thế này; bạn có thể muốn làm điều đó hơi khác:

Thêm phương pháp cho nhãn biết phần nào cần đánh dấu. Điều này có thể giống như thế này, giả sử bạn chỉ cần một khu vực được đánh dấu:

public void highlightRegion(int start, int end) { 
    // Set some field to tell you where the highlight starts and ends... 
} 

Nếu bạn cần nhiều vùng, chỉ cần có một ArrayList thay vì một trường đơn giản. Một phương pháp cho dehighlighting có lẽ sẽ hữu ích quá.

Bây giờ, bạn cần ghi đè phương thức paintComponent của JLabel. Ở đây bạn cần phải thực hiện một số bước riêng biệt, mà bạn có thể muốn tổ chức theo các phương pháp khác nhau hoặc một cái gì đó. Để đơn giản, tôi sẽ đặt tất cả trong phương pháp vẽ.

@Override 
protected void paintComponent(Graphics g) { 
    ... 

Trước tiên, bạn cần tìm ra kích thước vật lý của đánh dấu mà bạn có thể thực hiện bằng cách sử dụng lớp học đẹp FontMetrics. Tạo lớp học FontMetrics cho số Font bạn đang sử dụng.

FontMetrics metrics = new FontMetrics(getFont()); 

Bây giờ bạn có thể nhận được tất cả thông tin bạn cần để tạo hình chữ nhật sẽ là điểm nổi bật. Bạn sẽ cần vị trí bắt đầu, chiều cao và chiều rộng. Để có được điều này, bạn sẽ cần hai chuỗi con của văn bản 's JLabel như sau:

String start = getText().substring(0, startOfHighlight); 
    String text = getText().substring(startOfHighlight, endOfHighlight); 
    //You may also need to account for some offsets here: 
    int startX = metrics.stringWidth(start); 
    int startY = 0; //You probably have some vertical offset to add here. 
    int length = metrics.stringWidth(text); 
    int height = metrics.getHeight(); 

Bây giờ bạn có thể vẽ các khu vực nhấn mạnh trước khi rút ra phần còn lại của nhãn:

g.fillRect(startX, startY, length, height); 
    super.paintComponent(g); 
} 

Dĩ nhiên , nếu bạn muốn đánh dấu để mở rộng nhiều hàng, điều đó sẽ yêu cầu nhiều công việc hơn.

Nếu bạn đang tự hỏi, tôi đã thực sự viết một cái gì đó như thế này trước đây. Trên một ý thích, tôi quyết định viết thành phần loại vùng văn bản của riêng mình từ một số JPanel và đây là cách tôi xử lý nổi bật. Tái phát minh bánh xe có thể ngu ngốc trong một dự án thực tế, nhưng nó dạy cho bạn những thứ ngẫu nhiên có thể hữu ích ...

+0

Rất tiếc, cảm ơn phản hồi của bạn. Điều đó làm việc gần như hoàn hảo cho JLabels. Tuy nhiên tôi gặp phải một vấn đề. Nếu nhãn là setOpaque (true) như được yêu cầu trong tình huống của tôi, nó sẽ làm nổi bật không hiển thị. Điều này, tôi nghĩ, là do gọi super.paintComponent (g) sau khi thực hiện các bản vẽ tùy chỉnh. Tôi đã cố gắng vẽ bản vẽ làm nổi bật đầu tiên nhưng sau đó hình chữ nhật được tô sáng vẽ trên văn bản sẽ được tô sáng. Đó là một câu chuyện dài nhưng để có được bảng phân chia và một số thứ khác như hàng nổi bật để hiển thị trong trường hợp của tôi, tôi phải đặt nhãn thành mờ. Cảm ơn vì sự trả lời. – startoftext

+0

Vâng, trước tiên hãy thử gọi 'super.paintComponent (g)' và sử dụng 'g.setColor' để đặt màu thành một phần nào đó trong suốt (ví dụ:' new Color (0x33, 0x66, 0xFF, 0x66) 'là màu xanh dương) trước khi gọi 'fillRect'. –

+0

Cuối cùng tôi đã kết thúc về cơ bản thực hiện lại phương pháp thành phần sơn của riêng tôi để một cái gì đó mà làm việc cho mục đích của tôi. Và đã từ bỏ việc gọi phương thức thành phần sơn mẹ. Bạn trả lời là rất tốt đẹp và giải pháp khá tốt tại trả lời tiêu đề của bài đăng này mặc dù là liên quan đến một jlabel vì vậy tôi sẽ đánh dấu nó như được chấp nhận. Cảm ơn một nhóm Tikhon. – startoftext

2

Đó là một câu trả lời tuyệt vời, và có lẽ là giải pháp tốt nhất. Nhưng một sự thay thế mà một số có thể tìm thấy đơn giản hơn là sử dụng một JTextField thay vì một JLabel cho rendering sau đó bạn có thể sử dụng JTextfields làm nổi bật khả năng tức là

void highlightWhitespaceText(JTextField text) 
    { 
     text.setHighlighter(AbstractTableCellRenderer.defaultHighlighter); 
     try 
     { 
      Matcher m = AbstractTableCellRenderer.whitespaceStartPattern.matcher(text.getText()); 
      if (m.matches()) 
      { 
       text.getHighlighter().addHighlight(m.start(1), m.end(1), AbstractTableCellRenderer.highlightPainter); 
      } 
      m = AbstractTableCellRenderer.whitespaceEndPattern.matcher(text.getText()); 
      if (m.matches()) 
      { 
       text.getHighlighter().addHighlight(m.start(1), m.end(1), AbstractTableCellRenderer.highlightPainter); 
      } 
     } 
     catch (BadLocationException ble) 
     { 
      // 
     } 
    } 

Bạn có thể thay đổi các thuộc tính của một JTextField để nó trông giống như một JLabel trong khác tôn trọng.

2

Không thể chống lại việc ném cơ chế trang trí trình hiển thị SwingX vào vòng: cách của nó để giải quyết yêu cầu là thực hiện Công cụ đánh dấu làm việc đó. Thực tế là đã được thực hiện (mặc dù chưa được hỗ trợ chính thức) nhưng ẩn trong dự án SwingLabs-Demos, có tên là X/MatchingTextHighlighter (bạn sẽ cần cả hai) và gần đây đã cố định để đối phó với các biểu tượng, RToL-ComponentOrientation, alignment, ellipses ..

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