Java Canvas and Sprites Error - java

I have a given Canvas class, I want to load a Sprite with a special celltype and then draw it on my Canvas. I'm new to GUI and Canvas modelling, with the part of Code below I always get an "Unhandled type IO Exception Error " in line 3 where I Implement my sprite loader. I can easily draw Rectangles and else but I fail at loading my Sprite and convert it to an Image.
private class Canvas extends JPanel {
private static final long serialVersionUID = 1L;
public SpritesheetLoader SL=SpritesheetLoader.defaultLoader();
private Spritesheet S=SL.getSpritesheet("graphics/sprites/equipment/chest/tnecksweater-female");
Image I=S.getCel(0);
/**
* Creates a new canvas object
*/
public Canvas() {
super(true);
super.setBackground(new Color(0, 128, 0)); // middle green
}
/**
* Redraws the canvas
*
* #param g The graphics context to redraw with
*/
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
synchronized (UIPanel.this) {
if (canvasDrawer != null) {
canvasDrawer.draw(g);
}
}
g.drawImage(I, 10, 10, this);
}
}
Edit:
public class SpritesheetLoader {
private String filename;
private Map<String, ZipEntry> spritesheets = null;
// XML parser
private DocumentBuilder xmlParser = null;
private ZipFile zipFile;
public SpritesheetLoader(String filename) {
this.filename = filename;
try {
this.xmlParser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
} catch (ParserConfigurationException exn) {
throw new RuntimeException(exn);
}
}
#SuppressWarnings("unused")
private static void printDocument(Document doc, OutputStream out) {
// code by http://stackoverflow.com/users/203907/bozho
try {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
transformer.transform(new DOMSource(doc),
new StreamResult(new OutputStreamWriter(out, "UTF-8")));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void init() throws IOException {
if (spritesheets != null) {
return;
}
spritesheets = new HashMap<>();
this.zipFile = new ZipFile(this.filename);
Enumeration<? extends ZipEntry> zipIterator = zipFile.entries();
while (zipIterator.hasMoreElements()) {
ZipEntry z = zipIterator.nextElement();
if (z.getName().endsWith(".xml")) {
String name = z.getName().substring(0, z.getName().length() - 4);
spritesheets.put(name, z);
}
}
}
public Spritesheet getSpritesheet(String name) {
ZipEntry entry = spritesheets.get(name);
if (entry == null) {
return null;
}
SpritesheetParser parser = new SpritesheetParser();
parser.parseToplevel(getData(entry));
return parser.getSpritesheet();
}
private InputStream getData(ZipEntry entry) {
try {
InputStream s = zipFile.getInputStream(entry);
return s;
} catch (IOException exn) {
throw new RuntimeException(exn);
}
}
private InputStream getDataForFilename(String data) {
try {
ZipEntry entry = zipFile.getEntry(data);
if (entry == null) {
throw new RuntimeException("Missing file entry: " + data);
}
InputStream s = zipFile.getInputStream(entry);
return s;
} catch (IOException exn) {
throw new RuntimeException(exn);
}
}
public Set<? extends String> getSpritesheetNames() {
return spritesheets.keySet();
}
private static SpritesheetLoader DEFAULT = null;
public static SpritesheetLoader defaultLoader() throws IOException {
if (DEFAULT != null) {
return DEFAULT;
}
DEFAULT = new SpritesheetLoader(System.getProperty("user.home") + File.separator + "prgpr" + File.separator + "graphics.zip");
DEFAULT.init();
return DEFAULT;
}
public static void main(String[] args) throws IOException {
SpritesheetLoader loader = defaultLoader();
System.out.println(loader.getSpritesheetNames());
System.out.println(loader.getSpritesheet("graphics/sprites/equipment/chest/tnecksweater-female"));
}
private class SpritesheetParser {
private Spritesheet spritesheet;
public Spritesheet getSpritesheet() {
return spritesheet;
}
public Element parseDoc(InputStream indoc) {
Document doc;
try {
doc = xmlParser.parse(indoc);
} catch (SAXException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
return doc.getDocumentElement();
}
public Element includeIfNeeded(Element elt) {
if (elt.getTagName().equals("include")) {
return parseDoc(getDataForFilename(elt.getAttribute("file")));
}
return null;
}
private void parseImageSet(Element elt) {
if (spritesheet != null) { // already have a spritesheet; obey override semantics
return;
}
String filename = elt.getAttribute("src");
EnumSet<DyeChannel> dyeChannels = EnumSet.noneOf(DyeChannel.class);
int splitIndex;
if ((splitIndex = filename.indexOf('|')) > 0) {
int index = splitIndex + 1;
for (; index < filename.length(); index++) {
switch (filename.charAt(index)) {
case 'R': dyeChannels.add(DyeChannel.RED); break;
case 'G': dyeChannels.add(DyeChannel.GREEN); break;
case 'B': dyeChannels.add(DyeChannel.BLUE); break;
case 'C': dyeChannels.add(DyeChannel.CYAN); break;
case 'M': dyeChannels.add(DyeChannel.MAGENTA); break;
case 'Y': dyeChannels.add(DyeChannel.YELLOW); break;
case 'W': dyeChannels.add(DyeChannel.WHITE); break;
}
}
filename = filename.substring(0, splitIndex);
}
BufferedImage bufferedImage;
try {
bufferedImage = ImageIO.read(getDataForFilename(filename));
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
spritesheet = new Spritesheet(bufferedImage, dyeChannels);
if (elt.hasAttribute("width") && elt.hasAttribute("height")) {
spritesheet.setCelDimensions(Integer.parseInt(elt.getAttribute("width")), Integer.parseInt(elt.getAttribute("height")));
}
}
int intAttribute(Element elt, String name) {
if (elt.hasAttribute(name)) {
return Integer.parseInt(elt.getAttribute(name));
}
return 0;
}
private void parseAnimation(Element elt, String name) {
Direction direction = Direction.DEFAULT;
switch (elt.getAttribute("direction")) {
case "up": direction = Direction.UP; break;
case "down": direction = Direction.DOWN; break;
case "left": direction = Direction.LEFT; break;
case "right": direction = Direction.RIGHT; break;
}
Animation animation = new Animation();
boolean looping = true;
NodeList nl = elt.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node n = nl.item(i);
if (n instanceof Element) {
Element animationStep = (Element)n;
int xoffset = intAttribute(animationStep, "offsetX");
int yoffset = intAttribute(animationStep, "offsetY");
switch (animationStep.getTagName()) {
case "frame":
int index = intAttribute(animationStep, "index");
animation.addCelSequence(new CelSequence(
index, index, intAttribute(animationStep, "delay")).setOffsets(xoffset, yoffset));
break;
case "sequence":
animation.addCelSequence(new CelSequence(
intAttribute(animationStep, "start"),
intAttribute(animationStep, "end"),
intAttribute(animationStep, "delay")).setOffsets(xoffset, yoffset));
case "end":
looping = false;
break;
}
}
}
animation.setIsLooping(looping);
spritesheet.addAnimation(name, direction, animation);
}
private void parseAction(Element elt) {
String actionName = elt.getAttribute("name");
NodeList nl = elt.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node n = nl.item(i);
if (n instanceof Element) {
Element actionPart = (Element)n;
switch (actionPart.getTagName()) {
case "animation": parseAnimation(actionPart, actionName); break;
}
}
}
}
public void parseToplevel(InputStream docStream) {
parseToplevelElement(parseDoc(docStream));
}
public void parseToplevelElement(Element body) {
if (body == null) {
return;
}
if (!body.getTagName().equals("sprite")) {
System.err.println("Not a <sprite>");
return;
}
NodeList nl = body.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node n = nl.item(i);
if (n instanceof Element) {
Element elt = (Element) n;
switch (elt.getTagName()) {
case "imageset":
parseImageSet(elt);
break;
case "action":
parseAction(elt);
break;
case "include":
parseToplevelElement(includeIfNeeded(elt));
}
}
}
}
}
}

Related

Java Maze Solver - Stack does not pop when pop() is called

I'm working on an assignment where I have to solve a maze through backtracking (using a stack!) and the logic of the code is basically done, but the main problem is whenever I call pop() on my stack, it does not pop.So for now I have manually added (hardcoded) the parts in the maze where it is supposed to pop(). I am using my own stack that is using Linked Nodes and have ran JUnit and Main tests and it does indeed work (doubting myself here now). I have also used the Java stack and I get the same result.
Here is my code logic: As you can see in the method mazeSolver, at the bottom, I have a few if statements that check if i (operations performed) is at a certain point and it will "backtrack", but I am manually setting the position. The very last else statement is the part where I pop(). Any help would very much be appreciated.
public class MazeSolver {
private char[][] printMaze;
private char[][] solveMaze;
public MazeSolver() {
super();
}
private class Position {
private int x;
private int y;
Position(int y, int x) {
this.x = x;
this.y = y;
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
}
public boolean solve(boolean printUpdates) {
char space = ' ';
Stack<Position> stack = new Stack<Position>();
//Stack stack = new Stack();
Position cp = new Position(1, 0);
boolean done = true;
char c = 'C';
char x = 'X';
int i = 0;
while (done) {
// check right
if (printMaze[cp.getY()][cp.getX() + 1] == space && printMaze[cp.getY()][cp.getX() + 1] != x) {
cp.setX(cp.getX() + 1);
stack.push(cp);
printMaze[cp.getY()][cp.getX()] = 'C';
}
// check bottom
else if (printMaze[cp.getY() + 1][cp.getX()] == space && printMaze[cp.getY() + 1][cp.getX()] != x
&& printMaze[cp.getY() + 1][cp.getX()] != x) {
cp.setY(cp.getY() + 1);
stack.push(cp);
printMaze[cp.getY()][cp.getX()] = 'C';
}
// check top
else if (printMaze[cp.getY() - 1][cp.getX()] == space && printMaze[cp.getY() - 1][cp.getX()] != x) {
cp.setY(cp.getY() - 1);
stack.push(cp);
printMaze[cp.getY()][cp.getX()] = 'C';
}
// check left
else if (printMaze[cp.getY()][cp.getX() - 1] == space && printMaze[cp.getY()][cp.getX() - 1] != x) {
cp.setX(cp.getX() - 1);
stack.push(cp);
printMaze[cp.getY()][cp.getX()] = 'C';
}
//else {
/*
if (i == 6) {
printMaze[cp.getY()][cp.getX()] = 'X';
cp.setY(1);
cp.setX(5);
} else if (i == 27) {
printMaze[cp.getY()][cp.getX()] = 'X';
cp.setY(1);
cp.setX(20);
}
else if (i == 37) {
printMaze[cp.getY()][cp.getX()] = 'X';
cp.setY(2);
cp.setX(18);
}
else if (i == 68) {
printMaze[cp.getY()][cp.getX()] = 'X';
cp.setY(13);
cp.setX(22);
} else if (i == 69) {
printMaze[cp.getY()][cp.getX()] = 'X';
cp.setY(14);
cp.setX(22);
}
else if (i == 70) {
printMaze[cp.getY()][cp.getX()] = 'X';
cp.setY(15);
cp.setX(22);
} else if (i == 71) {
printMaze[cp.getY()][cp.getX()] = 'X';
cp.setY(16);
cp.setX(22);
} else if (i == 72) {
printMaze[cp.getY()][cp.getX()] = 'X';
cp.setY(17);
cp.setX(22);
} else if (i == 103) {
printMaze[cp.getY()][cp.getX()] = 'X';
cp.setY(21);
cp.setX(31);
} */else {
printMaze[cp.getY()][cp.getX()] = 'X';
stack.pop();
cp.setY(((Position) stack.top()).getY());
cp.setX(((Position) stack.top()).getX());
}
//}
i++;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
// System.out.println(stack.top().getX() + ", " + stack.top().getY());
System.out.println(cp.getY() + ", " + cp.getX() + " i = " + i);
printMaze();
}
System.out.println("success");
return false;
}
public void printMaze() {
for (int i = 0; i < printMaze.length; i++) {
for (int j = 0; j < printMaze[i].length; j++) {
System.out.print(printMaze[i][j]);
}
System.out.println("");
}
}
public boolean loadMaze(String filename) {
BufferedReader br = null;
FileReader fr = null;
ArrayList<String> lines = new ArrayList<String>();
try {
fr = new FileReader(filename);
br = new BufferedReader(fr);
String line;
br = new BufferedReader(new FileReader(filename));
while ((line = br.readLine()) != null) {
lines.add(line);
}
printMaze = new char[lines.size()][];
solveMaze = new char[lines.size()][];
for (int i = 0; i < lines.size(); i++) {
printMaze[i] = new char[lines.get(i).length()];
solveMaze[i] = new char[lines.get(i).length()];
for (int j = 0; j < lines.get(i).length(); j++) {
solveMaze[i][j] = lines.get(i).charAt(j);
printMaze[i][j] = lines.get(i).charAt(j);
if (solveMaze[i][j] == 'S') {
// hint you need to do this but you do not have the
// instance variable yet
// start = new Position(i, j);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)
br.close();
if (fr != null)
fr.close();
} catch (IOException ex) {
return false;
}
}
return true;
}
Here is my stack implementation if interested.
public class Stack<Item> implements StackInterface<Item> {
private int size;
private class Link {
private Item data;
public Link next;
public Link(Item data, Link next) {
this.data = data;
this.next = next;
}
public Item getData() {
return data;
}
}
private Link topStackLink = null;
public Stack() {
this.size = 0;
}
#Override
public void push(Item item) {
if (topStackLink == null) {
topStackLink = new Link(item, null);
} else {
topStackLink = new Link(item, topStackLink);
}
this.size++;
}
#Override
public void pop() {
// TODO Auto-generated method stub
if (topStackLink != null) {
topStackLink = topStackLink.next;
this.size--;
} else {
throw new java.util.EmptyStackException();
}
}
#Override
public Item top() {
if (topStackLink != null) {
return topStackLink.data;
} else {
throw new java.util.EmptyStackException();
}
}
#Override
public Item topAndPop() {
// TODO Auto-generated method stub
if (topStackLink != null) {
Item item = topStackLink.data;
pop();
return item;
} else {
throw new java.util.EmptyStackException();
}
}
#Override
public boolean isEmpty() {
if (topStackLink == null) {
return true;
} else {
return false;
}
}
#Override
public void makeEmpty() {
// TODO Auto-generated method stub
topStackLink = null;
this.size = 0;
}
#Override
public int size() {
return this.size;
}

program to show a progress bar while transferring all files from one server to another in java

i have written a java code to transfer files from one server to another using the concept of socket programming. now in the same code i also want to check for the network connection availability before each file is transferred. i also want that the files transferred should be transferred according to their numerical sequence. And while the files are being transferred the transfer progress of each file i.e the progress percentage bar should also be visible on the screen.
i will really appreciate if someone can help me with the code. i am posting the code i have written for file transfer.
ClientMain.java
import java.io.*;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class ClientMain {
private DirectoryTxr transmitter = null;
Socket clientSocket = null;
private boolean connectedStatus = false;
private String ipAddress;
String srcPath = null;
String dstPath = "";
public ClientMain() {
}
public void setIpAddress(String ip) {
this.ipAddress = ip;
}
public void setSrcPath(String path) {
this.srcPath = path;
}
public void setDstPath(String path) {
this.dstPath = path;
}
private void createConnection() {
Runnable connectRunnable = new Runnable() {
public void run() {
while (!connectedStatus) {
try {
clientSocket = new Socket(ipAddress, 3339);
connectedStatus = true;
transmitter = new DirectoryTxr(clientSocket, srcPath, dstPath);
} catch (IOException io) {
io.printStackTrace();
}
}
}
};
Thread connectionThread = new Thread(connectRunnable);
connectionThread.start();
}
public static void main(String[] args) {
ClientMain main = new ClientMain();
main.setIpAddress("10.6.3.92");
main.setSrcPath("E:/temp/movies/");
main.setDstPath("D:/tcp/movies");
main.createConnection();
}
}
(DirectoryTxr.java)
import java.io.*;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class DirectoryTxr {
Socket clientSocket = null;
String srcDir = null;
String dstDir = null;
byte[] readBuffer = new byte[1024];
private InputStream inStream = null;
private OutputStream outStream = null;
int state = 0;
final int permissionReqState = 1;
final int initialState = 0;
final int dirHeaderSendState = 2;
final int fileHeaderSendState = 3;
final int fileSendState = 4;
final int fileFinishedState = 5;
private boolean isLive = false;
private int numFiles = 0;
private int filePointer = 0;
String request = "May I send?";
String respServer = "Yes,You can";
String dirResponse = "Directory created...Please send files";
String fileHeaderRecvd = "File header received ...Send File";
String fileReceived = "File Received";
String dirFailedResponse = "Failed";
File[] opFileList = null;
public DirectoryTxr(Socket clientSocket, String srcDir, String dstDir) {
try {
this.clientSocket = clientSocket;
inStream = clientSocket.getInputStream();
outStream = clientSocket.getOutputStream();
isLive = true;
this.srcDir = srcDir;
this.dstDir = dstDir;
state = initialState;
readResponse(); //starting read thread
sendMessage(request);
state = permissionReqState;
} catch (IOException io) {
io.printStackTrace();
}
}
private void sendMessage(String message) {
try {
sendBytes(request.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
/**
* Thread to read response from server
*/
private void readResponse() {
Runnable readRunnable = new Runnable() {
public void run() {
while (isLive) {
try {
int num = inStream.read(readBuffer);
if (num > 0) {
byte[] tempArray = new byte[num];
System.arraycopy(readBuffer, 0, tempArray, 0, num);
processBytes(tempArray);
}
} catch (SocketException se) {
System.exit(0);
} catch (IOException io) {
io.printStackTrace();
isLive = false;
}
}
}
};
Thread readThread = new Thread(readRunnable);
readThread.start();
}
private void sendDirectoryHeader() {
File file = new File(srcDir);
if (file.isDirectory()) {
try {
String[] childFiles = file.list();
numFiles = childFiles.length;
String dirHeader = "$" + dstDir + "#" + numFiles + "&";
sendBytes(dirHeader.getBytes("UTF-8"));
} catch (UnsupportedEncodingException en) {
en.printStackTrace();
}
} else {
System.out.println(srcDir + " is not a valid directory");
}
}
private void sendFile(String dirName) {
File file = new File(dirName);
if (!file.isDirectory()) {
try {
int len = (int) file.length();
int buffSize = len / 8;
//to avoid the heap limitation
RandomAccessFile raf = new RandomAccessFile(file, "rw");
FileChannel channel = raf.getChannel();
int numRead = 0;
while (numRead >= 0) {
ByteBuffer buf = ByteBuffer.allocate(1024 * 100000);
numRead = channel.read(buf);
if (numRead > 0) {
byte[] array = new byte[numRead];
System.arraycopy(buf.array(), 0, array, 0, numRead);
sendBytes(array);
}
}
System.out.println("Finished");
} catch (IOException io) {
io.printStackTrace();
}
}
}
private void sendHeader(String fileName) {
try {
File file = new File(fileName);
if (file.isDirectory())
return;//avoiding child directories to avoid confusion
//if want we can sent them recursively
//with proper state transitions
String header = "&" + fileName + "#" + file.length() + "*";
sendHeader(header);
sendBytes(header.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
private void sendBytes(byte[] dataBytes) {
synchronized (clientSocket) {
if (outStream != null) {
try {
outStream.write(dataBytes);
outStream.flush();
} catch (IOException io) {
io.printStackTrace();
}
}
}
}
private void processBytes(byte[] data) {
try {
String parsedMessage = new String(data, "UTF-8");
System.out.println(parsedMessage);
setResponse(parsedMessage);
} catch (UnsupportedEncodingException u) {
u.printStackTrace();
}
}
private void setResponse(String message) {
if (message.trim().equalsIgnoreCase(respServer) && state == permissionReqState) {
state = dirHeaderSendState;
sendDirectoryHeader();
} else if (message.trim().equalsIgnoreCase(dirResponse) && state == dirHeaderSendState) {
state = fileHeaderSendState;
if (LocateDirectory()) {
createAndSendHeader();
} else {
System.out.println("Vacant or invalid directory");
}
} else if (message.trim().equalsIgnoreCase(fileHeaderRecvd) && state == fileHeaderSendState) {
state = fileSendState;
sendFile(opFileList[filePointer].toString());
state = fileFinishedState;
filePointer++;
} else if (message.trim().equalsIgnoreCase(fileReceived) && state == fileFinishedState) {
if (filePointer < numFiles) {
createAndSendHeader();
}
System.out.println("Successfully sent");
} else if (message.trim().equalsIgnoreCase(dirFailedResponse)) {
System.out.println("Going to exit....Error ");
// System.exit(0);
} else if (message.trim().equalsIgnoreCase("Thanks")) {
System.out.println("All files were copied");
}
}
private void closeSocket() {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private boolean LocateDirectory() {
boolean status = false;
File file = new File(srcDir);
if (file.isDirectory()) {
opFileList = file.listFiles();
numFiles = opFileList.length;
if (numFiles <= 0) {
System.out.println("No files found");
} else {
status = true;
}
}
return status;
}
private void createAndSendHeader() {
File opFile = opFileList[filePointer];
String header = "&" + opFile.getName() + "#" + opFile.length() + "*";
try {
state = fileHeaderSendState;
sendBytes(header.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
}
}
private void sendListFiles() {
createAndSendHeader();
}
}
(ServerMain.java)
public class ServerMain {
public ServerMain() {
}
public static void main(String[] args) {
DirectoryRcr dirRcr = new DirectoryRcr();
}
}
(DirectoryRcr.java)
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
public class DirectoryRcr {
String request = "May I send?";
String respServer = "Yes,You can";
String dirResponse = "Directory created...Please send files";
String dirFailedResponse = "Failed";
String fileHeaderRecvd = "File header received ...Send File";
String fileReceived = "File Received";
Socket socket = null;
OutputStream ioStream = null;
InputStream inStream = null;
boolean isLive = false;
int state = 0;
final int initialState = 0;
final int dirHeaderWait = 1;
final int dirWaitState = 2;
final int fileHeaderWaitState = 3;
final int fileContentWaitState = 4;
final int fileReceiveState = 5;
final int fileReceivedState = 6;
final int finalState = 7;
byte[] readBuffer = new byte[1024 * 100000];
long fileSize = 0;
String dir = "";
FileOutputStream foStream = null;
int fileCount = 0;
File dstFile = null;
public DirectoryRcr() {
acceptConnection();
}
private void acceptConnection() {
try {
ServerSocket server = new ServerSocket(3339);
socket = server.accept();
isLive = true;
ioStream = socket.getOutputStream();
inStream = socket.getInputStream();
state = initialState;
startReadThread();
} catch (IOException io) {
io.printStackTrace();
}
}
private void startReadThread() {
Thread readRunnable = new Thread() {
public void run() {
while (isLive) {
try {
int num = inStream.read(readBuffer);
if (num > 0) {
byte[] tempArray = new byte[num];
System.arraycopy(readBuffer, 0, tempArray, 0, num);
processBytes(tempArray);
}
sleep(100);
} catch (SocketException s) {
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException i) {
i.printStackTrace();
}
}
}
};
Thread readThread = new Thread(readRunnable);
readThread.start();
}
private void processBytes(byte[] buff) throws InterruptedException {
if (state == fileReceiveState || state == fileContentWaitState) {
//write to file
if (state == fileContentWaitState)
state = fileReceiveState;
fileSize = fileSize - buff.length;
writeToFile(buff);
if (fileSize == 0) {
state = fileReceivedState;
try {
foStream.close();
} catch (IOException io) {
io.printStackTrace();
}
System.out.println("Received " + dstFile.getName());
sendResponse(fileReceived);
fileCount--;
if (fileCount != 0) {
state = fileHeaderWaitState;
} else {
System.out.println("Finished");
state = finalState;
sendResponse("Thanks");
Thread.sleep(2000);
System.exit(0);
}
System.out.println("Received");
}
} else {
parseToUTF(buff);
}
}
private void parseToUTF(byte[] data) {
try {
String parsedMessage = new String(data, "UTF-8");
System.out.println(parsedMessage);
setResponse(parsedMessage);
} catch (UnsupportedEncodingException u) {
u.printStackTrace();
}
}
private void setResponse(String message) {
if (message.trim().equalsIgnoreCase(request) && state == initialState) {
sendResponse(respServer);
state = dirHeaderWait;
} else if (state == dirHeaderWait) {
if (createDirectory(message)) {
sendResponse(dirResponse);
state = fileHeaderWaitState;
} else {
sendResponse(dirFailedResponse);
System.out.println("Error occurred...Going to exit");
System.exit(0);
}
} else if (state == fileHeaderWaitState) {
createFile(message);
state = fileContentWaitState;
sendResponse(fileHeaderRecvd);
} else if (message.trim().equalsIgnoreCase(dirFailedResponse)) {
System.out.println("Error occurred ....");
System.exit(0);
}
}
private void sendResponse(String resp) {
try {
sendBytes(resp.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
private boolean createDirectory(String dirName) {
boolean status = false;
dir = dirName.substring(dirName.indexOf("$") + 1, dirName.indexOf("#"));
fileCount = Integer.parseInt(dirName.substring(dirName.indexOf("#") + 1, dirName.indexOf("&")));
if (new File(dir).mkdir()) {
status = true;
System.out.println("Successfully created directory " + dirName);
} else if (new File(dir).mkdirs()) {
status = true;
System.out.println("Directories were created " + dirName);
} else if (new File(dir).exists()) {
status = true;
System.out.println("Directory exists" + dirName);
} else {
System.out.println("Could not create directory " + dirName);
status = false;
}
return status;
}
private void createFile(String fileName) {
String file = fileName.substring(fileName.indexOf("&") + 1, fileName.indexOf("#"));
String lengthFile = fileName.substring(fileName.indexOf("#") + 1, fileName.indexOf("*"));
fileSize = Integer.parseInt(lengthFile);
dstFile = new File(dir + "/" + file);
try {
foStream = new FileOutputStream(dstFile);
System.out.println("Starting to receive " + dstFile.getName());
} catch (FileNotFoundException fn) {
fn.printStackTrace();
}
}
private void writeToFile(byte[] buff) {
try {
foStream.write(buff);
} catch (IOException io) {
io.printStackTrace();
}
}
private void sendBytes(byte[] dataBytes) {
synchronized (socket) {
if (ioStream != null) {
try {
ioStream.write(dataBytes);
} catch (IOException io) {
io.printStackTrace();
}
}
}
}
}
ClientMain.java and DirectoryTxr.java are the two classes under client application. ServerMain.java and DirectoryRcr.java are the two classes under Server application.
run the ClientMain.java and ServerMain.java
You can sort an array using Arrays.sort(...)
ie
String[] childFiles = file.list();
Arrays.sort(childFiles);
As I understand it, this will sort the files in natural order, based on the file name.
You can modify this by passing a custom Comparator...
Arrays.sort(childFiles, new Comparator<File>() {...}); // Fill out with your requirements...
Progress monitoring will come down to your requirements. Do you want to see only the overall progress of the number of files, the individual files, a combination of both?
What I've done in the past is pre-iterated the file list, calculated the total number of bytes to be copied and used a ProgressMonitor to display the overall bytes been copied...
Otherwise you will need to supply your own dialog. In either case, you will need use SwingUtilities.invokeLater to update them correctly.
Check out Concurrency in Swing for more details.
Network connectivity is subjective. You could simply send a special "message" to there server and wait for a response, but this only suggests that the message was sent and a recipt was received. It could just as easily fail when you start transfering the file again...

Counting distinct words with Threads

The objective is to count distinct words from a file.
UPDATE: Previous Code was successfully finished. Now I have to do the same but using threads (Oh man, I hate them...) and in addition I want to make it with semaphores for better flow.
Code contains some extra stuff left out from previous attempts, I'm trying to figure out what can be used..
I can read one word at a time but mostly I get a "null" in the container. So until I get anything from the container all the time I can't test the Sorter class and so on...
The new addition to the program is WordContainer class to store one word to pass it from reader to sorter:
package main2;
import java.util.ArrayList;
public class WordContainer
{
private ArrayList<String> words;
public synchronized String take()
{
String nextWord = null;
while (words.isEmpty())
{
try
{
wait();
}
catch (InterruptedException e)
{
}
}
nextWord = words.remove(0);
notify();
return nextWord;
}
public synchronized void put(String word)
{
while (words.size() > 999)
{
try
{
wait();
}
catch (InterruptedException e)
{
}
}
words.add(word);
notify();
}
}
DataSet Class combined with Sorter method resulting in Sorter Class:
package main2;
import java.util.concurrent.Semaphore;
public class Sorter extends Thread
{
private WordContainer wordContainer;
private int top;
private String[] elements;
private boolean stopped;
private Semaphore s;
private Semaphore s2;
public Sorter(WordContainer wordContainer, Semaphore s, Semaphore s2)
{
this.wordContainer = wordContainer;
elements = new String[1];
top = 0;
stopped = false;
this.s = s;
this.s2 = s2;
}
public void run()
{
String nextWord = wordContainer.take();
while (nextWord != null)
{
try
{
s.acquire();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
nextWord = wordContainer.take();
s2.release();
add(nextWord);
}
}
public void startSorting()
{
start();
}
public void stopSorting()
{
stopped = true;
}
public boolean member(String target)
{
if (top > 0)
{
return binarySearch(target, 0, top);
}
else
{
return false;
}
}
private boolean binarySearch(String target, int from, int to)
{
if (from == to - 1)
{
return elements[from].equals(target);
}
int middle = (to - from) / 2 + from;
if (elements[from].equals(target))
{
return true;
}
if (elements[middle].compareTo(target) > 0)
{
// search left
return binarySearch(target, from, middle);
}
else
{
// search right
return binarySearch(target, middle, to);
}
}
public void add(String nextElement)
{
if (top < elements.length)
{
elements[top++] = nextElement;
System.out.println("[" + top + "] " + nextElement);
sort();
}
else
{
String[] newArray = new String[elements.length * 2];
for (int i = 0; i < elements.length; i++)
{
newArray[i] = elements[i];
}
elements = newArray;
add(nextElement);
}
}
private void sort()
{
int index = 0;
while (index < top - 1)
{
if (elements[index].compareTo(elements[index + 1]) < 0)
{
index++;
}
else
{
String temp = elements[index];
elements[index] = elements[index + 1];
elements[index + 1] = temp;
if (index > 0)
{
index--;
}
}
}
}
public int size()
{
return top;
}
public String getSortedWords()
{
String w = "";
for (int i = 0; i < elements.length; i++)
{
w += elements[i] + ", ";
}
return w;
}
public int getNumberOfDistinctWords()
{
return top;
}
}
Reader Class now looks like this:
package main2;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.concurrent.Semaphore;
public class Reader extends Thread
{
private static final int whitespace = 45;
private static final int word = 48;
private static final int finished = -1;
private WordContainer wordContainer;
private Semaphore s;
private Semaphore s2;
private String[] wordsR;
private int state;
private BufferedReader reader;
private int nextFreeIndex;
public Reader(File words, WordContainer wordContainer, Semaphore s,
Semaphore s2)
{
state = whitespace;
try
{
reader = new BufferedReader(new FileReader(words));
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
nextFreeIndex = 0;
wordsR = new String[1];
this.wordContainer = wordContainer;
this.s = s;
this.s2 = s;
}
public void startReading()
{
start();
}
public void run()
{
String nextWord = readNext();
while (nextWord != null)
{
nextWord = readNext();
wordContainer.put(nextWord);
s.release();
try
{
s2.acquire();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
public String readNext()
{
int next;
StringBuffer nextWord = new StringBuffer();
while (true)
{
try
{
next = reader.read();
}
catch (IOException e)
{
next = -1;
}
char nextChar = (char) next;
switch (state)
{
case whitespace:
if (isWhiteSpace(nextChar))
{
state = whitespace;
}
else if (next == -1)
{
state = finished;
}
else
{
nextWord.append(nextChar);
state = word;
}
break;
case word:
if (isWhiteSpace(nextChar))
{
state = whitespace;
return nextWord.toString();
}
else if (next == -1)
{
state = finished;
return nextWord.toString();
}
else
{
nextWord.append(nextChar);
state = word;
}
break;
case finished:
return null;
}
}
}
private boolean isWhiteSpace(char nextChar)
{
switch (nextChar)
{
case '-':
case '"':
case ':':
case '\'':
case ')':
case '(':
case '!':
case ']':
case '?':
case '.':
case ',':
case ';':
case '[':
case ' ':
case '\t':
case '\n':
case '\r':
return true;
}
return false;
}
public void close()
{
try
{
reader.close();
}
catch (IOException e)
{
}
}
public String getWords()
{
return wordContainer.take();
}
}
Test Class
package test;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.Semaphore;
import main2.Reader;
import main2.Sorter;
import main2.WordContainer;
import junit.framework.Assert;
import junit.framework.TestCase;
public class TestDistinctWordsWithThreads extends TestCase
{
public void test() throws IOException, InterruptedException
{
File words = new File("resources" + File.separator + "AV1611Bible.txt");
if (!words.exists())
{
System.out.println("File [" + words.getAbsolutePath()
+ "] does not exist");
Assert.fail();
}
WordContainer container = new WordContainer();
Semaphore s = new Semaphore(0);
Semaphore s2 = new Semaphore(0);
Reader reader = new Reader(words, container, s, s2);
Sorter sorter = new Sorter(container, s, s2);
reader.startReading();
sorter.startSorting();
reader.join();
sorter.join();
System.out.println(reader.getWords());
Assert.assertTrue(sorter.getNumberOfDistinctWords() == 14720);
/*
* String bible = reader.getWords(); System.out.println(bible); String[]
* bible2 = sorter.getSortedWords(); System.out.println(bible2);
* assertTrue(bible2.length < bible.length());
*/
}
}
Why don't you sinply try something like:
public int countWords(File file) {
Scanner sc = new Scanner(file);
Set<String> allWords = new HashSet<String>();
while(sc.hasNext()) {
allWords.add(sc.next());
}
return allWords.size();
}

Java Serializable Saving

Well I have this class for a game I'm making, and I'm trying to save the ArrayList notes. When I logout, it properly print the size, for example if I have 5 notes, when I log out notes.getSize() would be 5, but when I log in, it gets reset back to nothing. Why isn't notes saving?
public class Notes implements Serializable {
private static final long serialVersionUID = -4947870743226160329L;
private ArrayList<Note> notes = new ArrayList<Note>(30);
public class Note implements Serializable {
private static final long serialVersionUID = -4589885080580317958L;
private int color = 0;
private String text = "";
public Note(int color, String text) {
this.setColor(color);
this.setText(text);
}
public void setText(String text) {
this.text = text;
}
public String getText() {
return text;
}
public void setColor(int color) {
this.color = color;
}
public int getColor() {
return color;
}
}
private transient Player player;
public Notes(Player p) {
this.player = p;
}
public void addNote(String text) {
System.out.println("Note Text: "+text);
if (text.length() > 50) {
player.getPackets().sendGameMessage("You can only enter notes up to 50 characters!");
return;
}
if (notes.size() < 30) {
notes.add(new Note(0, text));
} else {
player.getPackets().sendGameMessage("You cannot add more then 30 notes!");
return;
}
int NoteId = notes.size() - 1;
player.getPackets().sendConfig(1439, NoteId);
player.getTemporaryAttributtes().put("selectedNote", NoteId);
refreshNotes(false);
}
public void addNote(String text, int color) {
notes.add(new Note(color, text));
}
public void loadNotes() {
player.getPackets().sendIComponentSettings(34, 9, 0, 30, 2621470);
player.getPackets().sendHideIComponent(34, 3, false);
player.getPackets().sendHideIComponent(34, 44, false);
player.getPackets().sendIComponentText(34, 13, "Loading notes<br>Please wait...");
player.getPackets().sendConfig(1439, -1);
refreshNotes(true);
}
public void refreshNotes(boolean sendStartConfigs) {
for (int i = 0; i < 30; i++) {
player.getPackets().sendGlobalString(149 + i, i < notes.size() ? notes.get(i).getText() : "");
}
if (sendStartConfigs) {
for (int i = 1430; i < 1450; i++)
player.getPackets().sendConfig(i, i);
}
player.getPackets().sendConfig(1440, getFirstTotalColorValue());
player.getPackets().sendConfig(1441, getSecondTotalColorValue());
}
public int intColorValue(int color, int noteId) {
return (int) (Math.pow(4, noteId) * color);
}
public int getFirstTotalColorValue() {
int Color = 0;
for (int i = 0; i < 15; i++) {
if (notes.size() > i)
Color += intColorValue(notes.get(i).getColor(), i);
}
return Color;
}
public int getSecondTotalColorValue() {
int color = 0;
for (int i = 0; i < 15; i++) {
if (notes.size() > (i + 16))
color += intColorValue(notes.get(i + 16).getColor(), i);
}
return color;
}
public void deleteSelectedNote() {
if ((int)player.getTemporaryAttributtes().get("selectedNote") > -1) {
int slot = (int) player.getTemporaryAttributtes().get("selectedNote");
notes.remove(slot);
player.getTemporaryAttributtes().put("selectedNote", -1);
player.getPackets().sendConfig(1439, -1);
refreshNotes(false);
}
}
public void clear() {
notes.clear();
refreshNotes(false);
}
public void editNote(String string, int index) {
notes.get(index).setText(string);
refreshNotes(false);
}
public void setColor(int color, int index) {
notes.get(index).setColor(color);
refreshNotes(false);
}
public void deleteNote(int slot) {
notes.remove(slot);
refreshNotes(false);
}
public void setNotes(ArrayList<Note> setNotes) {
notes = setNotes;
refreshNotes(false);
}
}
And here is the class I manage saving/loading in
public class SerializableFilesManager {
private static final String PATH = "data/characters/";
private static final String BACKUP_PATH = "data/charactersBackup/";
public synchronized static final boolean containsPlayer(String username) {
return new File(PATH + username + ".p").exists();
}
public synchronized static Player loadPlayer(String username) {
try {
return (Player) loadSerializedFile(new File(PATH + username + ".p"));
} catch (Throwable e) {
Logger.handle(e);
}
try {
Logger.log("SerializableFilesManager", "Recovering account: "
+ username);
return (Player) loadSerializedFile(new File(BACKUP_PATH + username
+ ".p"));
} catch (Throwable e) {
Logger.handle(e);
}
return null;
}
public static boolean createBackup(String username) {
try {
Utils.copyFile(new File(PATH + username + ".p"), new File(
BACKUP_PATH + username + ".p"));
return true;
} catch (Throwable e) {
Logger.handle(e);
return false;
}
}
public synchronized static void savePlayer(Player player) {
try {
storeSerializableClass(player, new File(PATH + player.getUsername()
+ ".p"));
} catch (ConcurrentModificationException e) {
//happens because saving and logging out same time
} catch (Throwable e) {
Logger.handle(e);
}
}
public static final Object loadSerializedFile(File f) throws IOException,
ClassNotFoundException {
if (!f.exists())
return null;
ObjectInputStream in = new ObjectInputStream(new FileInputStream(f));
Object object = in.readObject();
in.close();
return object;
}
public static final void storeSerializableClass(Serializable o, File f)
throws IOException {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
out.writeObject(o);
out.close();
}
private SerializableFilesManager() {
}
}
Do NOT mark Player as transient, cause you are saving it, transient will prevent if from
getting saved, and will bring player to the default value of null, when deserialized.
Have you made the player class serializable ?
Its the Entire object graph that gets serialized or none... the purpose of transient is to make a particular member to be left off during serialization so that, the process of serialization goes smoothly.
For example, Suppose in a game we want to keep the progress of the player and hours of play for that session, but not the starting and ending times. So the starting and ending time can be made transient.
you should save your ArrayList with:
FileOutputStream fos = null;
ObjectOutputStream out = null;
try {
fos = new FileOutputStream("filename",false);
out = new ObjectOutputStream(fos);
out.writeObject(notes);
out.close();
System.out.println("Object Persisted");
} catch (IOException ex) {
ex.printStackTrace();
}
and when you open your project, import you Arraylist with:
FileInputStream fos;
try {
fos = new FileInputStream("filename");
ObjectInputStream oos = new ObjectInputStream(fos);
notes=(ArrayList) oos.readObject();
fos.close();
{
catch {
}
Thats because your Player is transient...I've tried to demonstrate your logic on other example...when Player was set to private, serialization has been successful and all data has been loaded back. Otherwise, when transient, Player reference was null, it loads only other serialized fields like int. When theres only a transient Player as field in class, the NullPointerException occurs, but ArrayList has size > 0.

How to implement draggable tab using Java Swing?

How do I implement a draggable tab using Java Swing? Instead of the static JTabbedPane I would like to drag-and-drop a tab to different position to rearrange the tabs.
EDIT: The Java Tutorials - Drag and Drop and Data Transfer.
Curses! Beaten to the punch by a Google search. Unfortunately it's true there is no easy way to create draggable tab panes (or any other components) in Swing. So whilst the example above is complete this one I've just written is a bit simpler. So it will hopefully demonstrate the more advanced techniques involved a bit clearer. The steps are:
Detect that a drag has occurred
Draw the dragged tab to an offscreen buffer
Track the mouse position whilst dragging occurs
Draw the tab in the buffer on top of the component.
The above example will give you what you want but if you want to really understand the techniques applied here it might be a better exercise to round off the edges of this example and add the extra features demonstrated above to it.
Or maybe I'm just disappointed because I spent time writing this solution when one already existed :p
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTabbedPane;
public class DraggableTabbedPane extends JTabbedPane {
private boolean dragging = false;
private Image tabImage = null;
private Point currentMouseLocation = null;
private int draggedTabIndex = 0;
public DraggableTabbedPane() {
super();
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
if(!dragging) {
// Gets the tab index based on the mouse position
int tabNumber = getUI().tabForCoordinate(DraggableTabbedPane.this, e.getX(), e.getY());
if(tabNumber >= 0) {
draggedTabIndex = tabNumber;
Rectangle bounds = getUI().getTabBounds(DraggableTabbedPane.this, tabNumber);
// Paint the tabbed pane to a buffer
Image totalImage = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics totalGraphics = totalImage.getGraphics();
totalGraphics.setClip(bounds);
// Don't be double buffered when painting to a static image.
setDoubleBuffered(false);
paintComponent(totalGraphics);
// Paint just the dragged tab to the buffer
tabImage = new BufferedImage(bounds.width, bounds.height, BufferedImage.TYPE_INT_ARGB);
Graphics graphics = tabImage.getGraphics();
graphics.drawImage(totalImage, 0, 0, bounds.width, bounds.height, bounds.x, bounds.y, bounds.x + bounds.width, bounds.y+bounds.height, DraggableTabbedPane.this);
dragging = true;
repaint();
}
} else {
currentMouseLocation = e.getPoint();
// Need to repaint
repaint();
}
super.mouseDragged(e);
}
});
addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
if(dragging) {
int tabNumber = getUI().tabForCoordinate(DraggableTabbedPane.this, e.getX(), 10);
if(tabNumber >= 0) {
Component comp = getComponentAt(draggedTabIndex);
String title = getTitleAt(draggedTabIndex);
removeTabAt(draggedTabIndex);
insertTab(title, null, comp, null, tabNumber);
}
}
dragging = false;
tabImage = null;
}
});
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// Are we dragging?
if(dragging && currentMouseLocation != null && tabImage != null) {
// Draw the dragged tab
g.drawImage(tabImage, currentMouseLocation.x, currentMouseLocation.y, this);
}
}
public static void main(String[] args) {
JFrame test = new JFrame("Tab test");
test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test.setSize(400, 400);
DraggableTabbedPane tabs = new DraggableTabbedPane();
tabs.addTab("One", new JButton("One"));
tabs.addTab("Two", new JButton("Two"));
tabs.addTab("Three", new JButton("Three"));
tabs.addTab("Four", new JButton("Four"));
test.add(tabs);
test.setVisible(true);
}
}
I liked Terai Atsuhiro san's DnDTabbedPane, but I wanted more from it. The original Terai implementation transfered tabs within the TabbedPane, but it would be nicer if I could drag from one TabbedPane to another.
Inspired by #Tom's effort, I decided to modify the code myself.
There are some details I added. For example, the ghost tab now slides along the tabbed pane instead of moving together with the mouse.
setAcceptor(TabAcceptor a_acceptor) should let the consumer code decide whether to let one tab transfer from one tabbed pane to another. The default acceptor always returns true.
/** Modified DnDTabbedPane.java
* http://java-swing-tips.blogspot.com/2008/04/drag-and-drop-tabs-in-jtabbedpane.html
* originally written by Terai Atsuhiro.
* so that tabs can be transfered from one pane to another.
* eed3si9n.
*/
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import java.awt.geom.*;
import java.awt.image.*;
import javax.swing.*;
public class DnDTabbedPane extends JTabbedPane {
public static final long serialVersionUID = 1L;
private static final int LINEWIDTH = 3;
private static final String NAME = "TabTransferData";
private final DataFlavor FLAVOR = new DataFlavor(
DataFlavor.javaJVMLocalObjectMimeType, NAME);
private static GhostGlassPane s_glassPane = new GhostGlassPane();
private boolean m_isDrawRect = false;
private final Rectangle2D m_lineRect = new Rectangle2D.Double();
private final Color m_lineColor = new Color(0, 100, 255);
private TabAcceptor m_acceptor = null;
public DnDTabbedPane() {
super();
final DragSourceListener dsl = new DragSourceListener() {
public void dragEnter(DragSourceDragEvent e) {
e.getDragSourceContext().setCursor(DragSource.DefaultMoveDrop);
}
public void dragExit(DragSourceEvent e) {
e.getDragSourceContext()
.setCursor(DragSource.DefaultMoveNoDrop);
m_lineRect.setRect(0, 0, 0, 0);
m_isDrawRect = false;
s_glassPane.setPoint(new Point(-1000, -1000));
s_glassPane.repaint();
}
public void dragOver(DragSourceDragEvent e) {
//e.getLocation()
//This method returns a Point indicating the cursor location in screen coordinates at the moment
TabTransferData data = getTabTransferData(e);
if (data == null) {
e.getDragSourceContext().setCursor(
DragSource.DefaultMoveNoDrop);
return;
} // if
/*
Point tabPt = e.getLocation();
SwingUtilities.convertPointFromScreen(tabPt, DnDTabbedPane.this);
if (DnDTabbedPane.this.contains(tabPt)) {
int targetIdx = getTargetTabIndex(tabPt);
int sourceIndex = data.getTabIndex();
if (getTabAreaBound().contains(tabPt)
&& (targetIdx >= 0)
&& (targetIdx != sourceIndex)
&& (targetIdx != sourceIndex + 1)) {
e.getDragSourceContext().setCursor(
DragSource.DefaultMoveDrop);
return;
} // if
e.getDragSourceContext().setCursor(
DragSource.DefaultMoveNoDrop);
return;
} // if
*/
e.getDragSourceContext().setCursor(
DragSource.DefaultMoveDrop);
}
public void dragDropEnd(DragSourceDropEvent e) {
m_isDrawRect = false;
m_lineRect.setRect(0, 0, 0, 0);
// m_dragTabIndex = -1;
if (hasGhost()) {
s_glassPane.setVisible(false);
s_glassPane.setImage(null);
}
}
public void dropActionChanged(DragSourceDragEvent e) {
}
};
final DragGestureListener dgl = new DragGestureListener() {
public void dragGestureRecognized(DragGestureEvent e) {
// System.out.println("dragGestureRecognized");
Point tabPt = e.getDragOrigin();
int dragTabIndex = indexAtLocation(tabPt.x, tabPt.y);
if (dragTabIndex < 0) {
return;
} // if
initGlassPane(e.getComponent(), e.getDragOrigin(), dragTabIndex);
try {
e.startDrag(DragSource.DefaultMoveDrop,
new TabTransferable(DnDTabbedPane.this, dragTabIndex), dsl);
} catch (InvalidDnDOperationException idoe) {
idoe.printStackTrace();
}
}
};
//dropTarget =
new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE,
new CDropTargetListener(), true);
new DragSource().createDefaultDragGestureRecognizer(this,
DnDConstants.ACTION_COPY_OR_MOVE, dgl);
m_acceptor = new TabAcceptor() {
public boolean isDropAcceptable(DnDTabbedPane a_component, int a_index) {
return true;
}
};
}
public TabAcceptor getAcceptor() {
return m_acceptor;
}
public void setAcceptor(TabAcceptor a_value) {
m_acceptor = a_value;
}
private TabTransferData getTabTransferData(DropTargetDropEvent a_event) {
try {
TabTransferData data = (TabTransferData) a_event.getTransferable().getTransferData(FLAVOR);
return data;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private TabTransferData getTabTransferData(DropTargetDragEvent a_event) {
try {
TabTransferData data = (TabTransferData) a_event.getTransferable().getTransferData(FLAVOR);
return data;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private TabTransferData getTabTransferData(DragSourceDragEvent a_event) {
try {
TabTransferData data = (TabTransferData) a_event.getDragSourceContext()
.getTransferable().getTransferData(FLAVOR);
return data;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
class TabTransferable implements Transferable {
private TabTransferData m_data = null;
public TabTransferable(DnDTabbedPane a_tabbedPane, int a_tabIndex) {
m_data = new TabTransferData(DnDTabbedPane.this, a_tabIndex);
}
public Object getTransferData(DataFlavor flavor) {
return m_data;
// return DnDTabbedPane.this;
}
public DataFlavor[] getTransferDataFlavors() {
DataFlavor[] f = new DataFlavor[1];
f[0] = FLAVOR;
return f;
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.getHumanPresentableName().equals(NAME);
}
}
class TabTransferData {
private DnDTabbedPane m_tabbedPane = null;
private int m_tabIndex = -1;
public TabTransferData() {
}
public TabTransferData(DnDTabbedPane a_tabbedPane, int a_tabIndex) {
m_tabbedPane = a_tabbedPane;
m_tabIndex = a_tabIndex;
}
public DnDTabbedPane getTabbedPane() {
return m_tabbedPane;
}
public void setTabbedPane(DnDTabbedPane pane) {
m_tabbedPane = pane;
}
public int getTabIndex() {
return m_tabIndex;
}
public void setTabIndex(int index) {
m_tabIndex = index;
}
}
private Point buildGhostLocation(Point a_location) {
Point retval = new Point(a_location);
switch (getTabPlacement()) {
case JTabbedPane.TOP: {
retval.y = 1;
retval.x -= s_glassPane.getGhostWidth() / 2;
} break;
case JTabbedPane.BOTTOM: {
retval.y = getHeight() - 1 - s_glassPane.getGhostHeight();
retval.x -= s_glassPane.getGhostWidth() / 2;
} break;
case JTabbedPane.LEFT: {
retval.x = 1;
retval.y -= s_glassPane.getGhostHeight() / 2;
} break;
case JTabbedPane.RIGHT: {
retval.x = getWidth() - 1 - s_glassPane.getGhostWidth();
retval.y -= s_glassPane.getGhostHeight() / 2;
} break;
} // switch
retval = SwingUtilities.convertPoint(DnDTabbedPane.this,
retval, s_glassPane);
return retval;
}
class CDropTargetListener implements DropTargetListener {
public void dragEnter(DropTargetDragEvent e) {
// System.out.println("DropTarget.dragEnter: " + DnDTabbedPane.this);
if (isDragAcceptable(e)) {
e.acceptDrag(e.getDropAction());
} else {
e.rejectDrag();
} // if
}
public void dragExit(DropTargetEvent e) {
// System.out.println("DropTarget.dragExit: " + DnDTabbedPane.this);
m_isDrawRect = false;
}
public void dropActionChanged(DropTargetDragEvent e) {
}
public void dragOver(final DropTargetDragEvent e) {
TabTransferData data = getTabTransferData(e);
if (getTabPlacement() == JTabbedPane.TOP
|| getTabPlacement() == JTabbedPane.BOTTOM) {
initTargetLeftRightLine(getTargetTabIndex(e.getLocation()), data);
} else {
initTargetTopBottomLine(getTargetTabIndex(e.getLocation()), data);
} // if-else
repaint();
if (hasGhost()) {
s_glassPane.setPoint(buildGhostLocation(e.getLocation()));
s_glassPane.repaint();
}
}
public void drop(DropTargetDropEvent a_event) {
// System.out.println("DropTarget.drop: " + DnDTabbedPane.this);
if (isDropAcceptable(a_event)) {
convertTab(getTabTransferData(a_event),
getTargetTabIndex(a_event.getLocation()));
a_event.dropComplete(true);
} else {
a_event.dropComplete(false);
} // if-else
m_isDrawRect = false;
repaint();
}
public boolean isDragAcceptable(DropTargetDragEvent e) {
Transferable t = e.getTransferable();
if (t == null) {
return false;
} // if
DataFlavor[] flavor = e.getCurrentDataFlavors();
if (!t.isDataFlavorSupported(flavor[0])) {
return false;
} // if
TabTransferData data = getTabTransferData(e);
if (DnDTabbedPane.this == data.getTabbedPane()
&& data.getTabIndex() >= 0) {
return true;
} // if
if (DnDTabbedPane.this != data.getTabbedPane()) {
if (m_acceptor != null) {
return m_acceptor.isDropAcceptable(data.getTabbedPane(), data.getTabIndex());
} // if
} // if
return false;
}
public boolean isDropAcceptable(DropTargetDropEvent e) {
Transferable t = e.getTransferable();
if (t == null) {
return false;
} // if
DataFlavor[] flavor = e.getCurrentDataFlavors();
if (!t.isDataFlavorSupported(flavor[0])) {
return false;
} // if
TabTransferData data = getTabTransferData(e);
if (DnDTabbedPane.this == data.getTabbedPane()
&& data.getTabIndex() >= 0) {
return true;
} // if
if (DnDTabbedPane.this != data.getTabbedPane()) {
if (m_acceptor != null) {
return m_acceptor.isDropAcceptable(data.getTabbedPane(), data.getTabIndex());
} // if
} // if
return false;
}
}
private boolean m_hasGhost = true;
public void setPaintGhost(boolean flag) {
m_hasGhost = flag;
}
public boolean hasGhost() {
return m_hasGhost;
}
/**
* returns potential index for drop.
* #param a_point point given in the drop site component's coordinate
* #return returns potential index for drop.
*/
private int getTargetTabIndex(Point a_point) {
boolean isTopOrBottom = getTabPlacement() == JTabbedPane.TOP
|| getTabPlacement() == JTabbedPane.BOTTOM;
// if the pane is empty, the target index is always zero.
if (getTabCount() == 0) {
return 0;
} // if
for (int i = 0; i < getTabCount(); i++) {
Rectangle r = getBoundsAt(i);
if (isTopOrBottom) {
r.setRect(r.x - r.width / 2, r.y, r.width, r.height);
} else {
r.setRect(r.x, r.y - r.height / 2, r.width, r.height);
} // if-else
if (r.contains(a_point)) {
return i;
} // if
} // for
Rectangle r = getBoundsAt(getTabCount() - 1);
if (isTopOrBottom) {
int x = r.x + r.width / 2;
r.setRect(x, r.y, getWidth() - x, r.height);
} else {
int y = r.y + r.height / 2;
r.setRect(r.x, y, r.width, getHeight() - y);
} // if-else
return r.contains(a_point) ? getTabCount() : -1;
}
private void convertTab(TabTransferData a_data, int a_targetIndex) {
DnDTabbedPane source = a_data.getTabbedPane();
int sourceIndex = a_data.getTabIndex();
if (sourceIndex < 0) {
return;
} // if
Component cmp = source.getComponentAt(sourceIndex);
String str = source.getTitleAt(sourceIndex);
if (this != source) {
source.remove(sourceIndex);
if (a_targetIndex == getTabCount()) {
addTab(str, cmp);
} else {
if (a_targetIndex < 0) {
a_targetIndex = 0;
} // if
insertTab(str, null, cmp, null, a_targetIndex);
} // if
setSelectedComponent(cmp);
// System.out.println("press="+sourceIndex+" next="+a_targetIndex);
return;
} // if
if (a_targetIndex < 0 || sourceIndex == a_targetIndex) {
//System.out.println("press="+prev+" next="+next);
return;
} // if
if (a_targetIndex == getTabCount()) {
//System.out.println("last: press="+prev+" next="+next);
source.remove(sourceIndex);
addTab(str, cmp);
setSelectedIndex(getTabCount() - 1);
} else if (sourceIndex > a_targetIndex) {
//System.out.println(" >: press="+prev+" next="+next);
source.remove(sourceIndex);
insertTab(str, null, cmp, null, a_targetIndex);
setSelectedIndex(a_targetIndex);
} else {
//System.out.println(" <: press="+prev+" next="+next);
source.remove(sourceIndex);
insertTab(str, null, cmp, null, a_targetIndex - 1);
setSelectedIndex(a_targetIndex - 1);
}
}
private void initTargetLeftRightLine(int next, TabTransferData a_data) {
if (next < 0) {
m_lineRect.setRect(0, 0, 0, 0);
m_isDrawRect = false;
return;
} // if
if ((a_data.getTabbedPane() == this)
&& (a_data.getTabIndex() == next
|| next - a_data.getTabIndex() == 1)) {
m_lineRect.setRect(0, 0, 0, 0);
m_isDrawRect = false;
} else if (getTabCount() == 0) {
m_lineRect.setRect(0, 0, 0, 0);
m_isDrawRect = false;
return;
} else if (next == 0) {
Rectangle rect = getBoundsAt(0);
m_lineRect.setRect(-LINEWIDTH / 2, rect.y, LINEWIDTH, rect.height);
m_isDrawRect = true;
} else if (next == getTabCount()) {
Rectangle rect = getBoundsAt(getTabCount() - 1);
m_lineRect.setRect(rect.x + rect.width - LINEWIDTH / 2, rect.y,
LINEWIDTH, rect.height);
m_isDrawRect = true;
} else {
Rectangle rect = getBoundsAt(next - 1);
m_lineRect.setRect(rect.x + rect.width - LINEWIDTH / 2, rect.y,
LINEWIDTH, rect.height);
m_isDrawRect = true;
}
}
private void initTargetTopBottomLine(int next, TabTransferData a_data) {
if (next < 0) {
m_lineRect.setRect(0, 0, 0, 0);
m_isDrawRect = false;
return;
} // if
if ((a_data.getTabbedPane() == this)
&& (a_data.getTabIndex() == next
|| next - a_data.getTabIndex() == 1)) {
m_lineRect.setRect(0, 0, 0, 0);
m_isDrawRect = false;
} else if (getTabCount() == 0) {
m_lineRect.setRect(0, 0, 0, 0);
m_isDrawRect = false;
return;
} else if (next == getTabCount()) {
Rectangle rect = getBoundsAt(getTabCount() - 1);
m_lineRect.setRect(rect.x, rect.y + rect.height - LINEWIDTH / 2,
rect.width, LINEWIDTH);
m_isDrawRect = true;
} else if (next == 0) {
Rectangle rect = getBoundsAt(0);
m_lineRect.setRect(rect.x, -LINEWIDTH / 2, rect.width, LINEWIDTH);
m_isDrawRect = true;
} else {
Rectangle rect = getBoundsAt(next - 1);
m_lineRect.setRect(rect.x, rect.y + rect.height - LINEWIDTH / 2,
rect.width, LINEWIDTH);
m_isDrawRect = true;
}
}
private void initGlassPane(Component c, Point tabPt, int a_tabIndex) {
//Point p = (Point) pt.clone();
getRootPane().setGlassPane(s_glassPane);
if (hasGhost()) {
Rectangle rect = getBoundsAt(a_tabIndex);
BufferedImage image = new BufferedImage(c.getWidth(),
c.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
c.paint(g);
image = image.getSubimage(rect.x, rect.y, rect.width, rect.height);
s_glassPane.setImage(image);
} // if
s_glassPane.setPoint(buildGhostLocation(tabPt));
s_glassPane.setVisible(true);
}
private Rectangle getTabAreaBound() {
Rectangle lastTab = getUI().getTabBounds(this, getTabCount() - 1);
return new Rectangle(0, 0, getWidth(), lastTab.y + lastTab.height);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (m_isDrawRect) {
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(m_lineColor);
g2.fill(m_lineRect);
} // if
}
public interface TabAcceptor {
boolean isDropAcceptable(DnDTabbedPane a_component, int a_index);
}
}
class GhostGlassPane extends JPanel {
public static final long serialVersionUID = 1L;
private final AlphaComposite m_composite;
private Point m_location = new Point(0, 0);
private BufferedImage m_draggingGhost = null;
public GhostGlassPane() {
setOpaque(false);
m_composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f);
}
public void setImage(BufferedImage draggingGhost) {
m_draggingGhost = draggingGhost;
}
public void setPoint(Point a_location) {
m_location.x = a_location.x;
m_location.y = a_location.y;
}
public int getGhostWidth() {
if (m_draggingGhost == null) {
return 0;
} // if
return m_draggingGhost.getWidth(this);
}
public int getGhostHeight() {
if (m_draggingGhost == null) {
return 0;
} // if
return m_draggingGhost.getHeight(this);
}
public void paintComponent(Graphics g) {
if (m_draggingGhost == null) {
return;
} // if
Graphics2D g2 = (Graphics2D) g;
g2.setComposite(m_composite);
g2.drawImage(m_draggingGhost, (int) m_location.getX(), (int) m_location.getY(), null);
}
}
Found this code out there on the tubes:
class DnDTabbedPane extends JTabbedPane {
private static final int LINEWIDTH = 3;
private static final String NAME = "test";
private final GhostGlassPane glassPane = new GhostGlassPane();
private final Rectangle2D lineRect = new Rectangle2D.Double();
private final Color lineColor = new Color(0, 100, 255);
//private final DragSource dragSource = new DragSource();
//private final DropTarget dropTarget;
private int dragTabIndex = -1;
public DnDTabbedPane() {
super();
final DragSourceListener dsl = new DragSourceListener() {
public void dragEnter(DragSourceDragEvent e) {
e.getDragSourceContext().setCursor(DragSource.DefaultMoveDrop);
}
public void dragExit(DragSourceEvent e) {
e.getDragSourceContext().setCursor(DragSource.DefaultMoveNoDrop);
lineRect.setRect(0,0,0,0);
glassPane.setPoint(new Point(-1000,-1000));
glassPane.repaint();
}
public void dragOver(DragSourceDragEvent e) {
//e.getLocation()
//This method returns a Point indicating the cursor location in screen coordinates at the moment
Point tabPt = e.getLocation();
SwingUtilities.convertPointFromScreen(tabPt, DnDTabbedPane.this);
Point glassPt = e.getLocation();
SwingUtilities.convertPointFromScreen(glassPt, glassPane);
int targetIdx = getTargetTabIndex(glassPt);
if(getTabAreaBound().contains(tabPt) && targetIdx>=0 &&
targetIdx!=dragTabIndex && targetIdx!=dragTabIndex+1) {
e.getDragSourceContext().setCursor(DragSource.DefaultMoveDrop);
}else{
e.getDragSourceContext().setCursor(DragSource.DefaultMoveNoDrop);
}
}
public void dragDropEnd(DragSourceDropEvent e) {
lineRect.setRect(0,0,0,0);
dragTabIndex = -1;
if(hasGhost()) {
glassPane.setVisible(false);
glassPane.setImage(null);
}
}
public void dropActionChanged(DragSourceDragEvent e) {}
};
final Transferable t = new Transferable() {
private final DataFlavor FLAVOR = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType, NAME);
public Object getTransferData(DataFlavor flavor) {
return DnDTabbedPane.this;
}
public DataFlavor[] getTransferDataFlavors() {
DataFlavor[] f = new DataFlavor[1];
f[0] = this.FLAVOR;
return f;
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.getHumanPresentableName().equals(NAME);
}
};
final DragGestureListener dgl = new DragGestureListener() {
public void dragGestureRecognized(DragGestureEvent e) {
Point tabPt = e.getDragOrigin();
dragTabIndex = indexAtLocation(tabPt.x, tabPt.y);
if(dragTabIndex<0) return;
initGlassPane(e.getComponent(), e.getDragOrigin());
try{
e.startDrag(DragSource.DefaultMoveDrop, t, dsl);
}catch(InvalidDnDOperationException idoe) {
idoe.printStackTrace();
}
}
};
//dropTarget =
new DropTarget(glassPane, DnDConstants.ACTION_COPY_OR_MOVE, new CDropTargetListener(), true);
new DragSource().createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, dgl);
}
class CDropTargetListener implements DropTargetListener{
public void dragEnter(DropTargetDragEvent e) {
if(isDragAcceptable(e)) e.acceptDrag(e.getDropAction());
else e.rejectDrag();
}
public void dragExit(DropTargetEvent e) {}
public void dropActionChanged(DropTargetDragEvent e) {}
public void dragOver(final DropTargetDragEvent e) {
if(getTabPlacement()==JTabbedPane.TOP || getTabPlacement()==JTabbedPane.BOTTOM) {
initTargetLeftRightLine(getTargetTabIndex(e.getLocation()));
}else{
initTargetTopBottomLine(getTargetTabIndex(e.getLocation()));
}
repaint();
if(hasGhost()) {
glassPane.setPoint(e.getLocation());
glassPane.repaint();
}
}
public void drop(DropTargetDropEvent e) {
if(isDropAcceptable(e)) {
convertTab(dragTabIndex, getTargetTabIndex(e.getLocation()));
e.dropComplete(true);
}else{
e.dropComplete(false);
}
repaint();
}
public boolean isDragAcceptable(DropTargetDragEvent e) {
Transferable t = e.getTransferable();
if(t==null) return false;
DataFlavor[] f = e.getCurrentDataFlavors();
if(t.isDataFlavorSupported(f[0]) && dragTabIndex>=0) {
return true;
}
return false;
}
public boolean isDropAcceptable(DropTargetDropEvent e) {
Transferable t = e.getTransferable();
if(t==null) return false;
DataFlavor[] f = t.getTransferDataFlavors();
if(t.isDataFlavorSupported(f[0]) && dragTabIndex>=0) {
return true;
}
return false;
}
}
private boolean hasGhost = true;
public void setPaintGhost(boolean flag) {
hasGhost = flag;
}
public boolean hasGhost() {
return hasGhost;
}
private int getTargetTabIndex(Point glassPt) {
Point tabPt = SwingUtilities.convertPoint(glassPane, glassPt, DnDTabbedPane.this);
boolean isTB = getTabPlacement()==JTabbedPane.TOP || getTabPlacement()==JTabbedPane.BOTTOM;
for(int i=0;i<getTabCount();i++) {
Rectangle r = getBoundsAt(i);
if(isTB) r.setRect(r.x-r.width/2, r.y, r.width, r.height);
else r.setRect(r.x, r.y-r.height/2, r.width, r.height);
if(r.contains(tabPt)) return i;
}
Rectangle r = getBoundsAt(getTabCount()-1);
if(isTB) r.setRect(r.x+r.width/2, r.y, r.width, r.height);
else r.setRect(r.x, r.y+r.height/2, r.width, r.height);
return r.contains(tabPt)?getTabCount():-1;
}
private void convertTab(int prev, int next) {
if(next<0 || prev==next) {
//System.out.println("press="+prev+" next="+next);
return;
}
Component cmp = getComponentAt(prev);
String str = getTitleAt(prev);
if(next==getTabCount()) {
//System.out.println("last: press="+prev+" next="+next);
remove(prev);
addTab(str, cmp);
setSelectedIndex(getTabCount()-1);
}else if(prev>next) {
//System.out.println(" >: press="+prev+" next="+next);
remove(prev);
insertTab(str, null, cmp, null, next);
setSelectedIndex(next);
}else{
//System.out.println(" <: press="+prev+" next="+next);
remove(prev);
insertTab(str, null, cmp, null, next-1);
setSelectedIndex(next-1);
}
}
private void initTargetLeftRightLine(int next) {
if(next<0 || dragTabIndex==next || next-dragTabIndex==1) {
lineRect.setRect(0,0,0,0);
}else if(next==getTabCount()) {
Rectangle rect = getBoundsAt(getTabCount()-1);
lineRect.setRect(rect.x+rect.width-LINEWIDTH/2,rect.y,LINEWIDTH,rect.height);
}else if(next==0) {
Rectangle rect = getBoundsAt(0);
lineRect.setRect(-LINEWIDTH/2,rect.y,LINEWIDTH,rect.height);
}else{
Rectangle rect = getBoundsAt(next-1);
lineRect.setRect(rect.x+rect.width-LINEWIDTH/2,rect.y,LINEWIDTH,rect.height);
}
}
private void initTargetTopBottomLine(int next) {
if(next<0 || dragTabIndex==next || next-dragTabIndex==1) {
lineRect.setRect(0,0,0,0);
}else if(next==getTabCount()) {
Rectangle rect = getBoundsAt(getTabCount()-1);
lineRect.setRect(rect.x,rect.y+rect.height-LINEWIDTH/2,rect.width,LINEWIDTH);
}else if(next==0) {
Rectangle rect = getBoundsAt(0);
lineRect.setRect(rect.x,-LINEWIDTH/2,rect.width,LINEWIDTH);
}else{
Rectangle rect = getBoundsAt(next-1);
lineRect.setRect(rect.x,rect.y+rect.height-LINEWIDTH/2,rect.width,LINEWIDTH);
}
}
private void initGlassPane(Component c, Point tabPt) {
//Point p = (Point) pt.clone();
getRootPane().setGlassPane(glassPane);
if(hasGhost()) {
Rectangle rect = getBoundsAt(dragTabIndex);
BufferedImage image = new BufferedImage(c.getWidth(), c.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
c.paint(g);
image = image.getSubimage(rect.x,rect.y,rect.width,rect.height);
glassPane.setImage(image);
}
Point glassPt = SwingUtilities.convertPoint(c, tabPt, glassPane);
glassPane.setPoint(glassPt);
glassPane.setVisible(true);
}
private Rectangle getTabAreaBound() {
Rectangle lastTab = getUI().getTabBounds(this, getTabCount()-1);
return new Rectangle(0,0,getWidth(),lastTab.y+lastTab.height);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if(dragTabIndex>=0) {
Graphics2D g2 = (Graphics2D)g;
g2.setPaint(lineColor);
g2.fill(lineRect);
}
}
}
class GhostGlassPane extends JPanel {
private final AlphaComposite composite;
private Point location = new Point(0, 0);
private BufferedImage draggingGhost = null;
public GhostGlassPane() {
setOpaque(false);
composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
}
public void setImage(BufferedImage draggingGhost) {
this.draggingGhost = draggingGhost;
}
public void setPoint(Point location) {
this.location = location;
}
public void paintComponent(Graphics g) {
if(draggingGhost == null) return;
Graphics2D g2 = (Graphics2D) g;
g2.setComposite(composite);
double xx = location.getX() - (draggingGhost.getWidth(this) /2d);
double yy = location.getY() - (draggingGhost.getHeight(this)/2d);
g2.drawImage(draggingGhost, (int)xx, (int)yy , null);
}
}
#Tony: It looks like Euguenes solution just overlooks preserving TabComponents during a swap.
The convertTab method just needs to remember the TabComponent and set it to the new tabs it makes.
Try using this:
private void convertTab(TabTransferData a_data, int a_targetIndex) {
DnDTabbedPane source = a_data.getTabbedPane();
System.out.println("this=source? " + (this == source));
int sourceIndex = a_data.getTabIndex();
if (sourceIndex < 0) {
return;
} // if
//Save the tab's component, title, and TabComponent.
Component cmp = source.getComponentAt(sourceIndex);
String str = source.getTitleAt(sourceIndex);
Component tcmp = source.getTabComponentAt(sourceIndex);
if (this != source) {
source.remove(sourceIndex);
if (a_targetIndex == getTabCount()) {
addTab(str, cmp);
setTabComponentAt(getTabCount()-1, tcmp);
} else {
if (a_targetIndex < 0) {
a_targetIndex = 0;
} // if
insertTab(str, null, cmp, null, a_targetIndex);
setTabComponentAt(a_targetIndex, tcmp);
} // if
setSelectedComponent(cmp);
return;
} // if
if (a_targetIndex < 0 || sourceIndex == a_targetIndex) {
return;
} // if
if (a_targetIndex == getTabCount()) {
source.remove(sourceIndex);
addTab(str, cmp);
setTabComponentAt(getTabCount() - 1, tcmp);
setSelectedIndex(getTabCount() - 1);
} else if (sourceIndex > a_targetIndex) {
source.remove(sourceIndex);
insertTab(str, null, cmp, null, a_targetIndex);
setTabComponentAt(a_targetIndex, tcmp);
setSelectedIndex(a_targetIndex);
} else {
source.remove(sourceIndex);
insertTab(str, null, cmp, null, a_targetIndex - 1);
setTabComponentAt(a_targetIndex - 1, tcmp);
setSelectedIndex(a_targetIndex - 1);
}
}
Add this to isDragAcceptable to avoid Exceptions:
boolean transferDataFlavorFound = false;
for (DataFlavor transferDataFlavor : t.getTransferDataFlavors()) {
if (FLAVOR.equals(transferDataFlavor)) {
transferDataFlavorFound = true;
break;
}
}
if (transferDataFlavorFound == false) {
return false;
}

Categories